Java中鎖分類
鎖的分類大致如下:
公平鎖/非公平鎖
可重入鎖/不可重入鎖
獨享鎖/共享鎖
樂觀鎖/悲觀鎖
分段鎖
1、公平鎖/非公平鎖
公平鎖就是嚴格按照線程啟動的順序來執行的,不允許其他線程插隊執行的;而非公平鎖是允許插隊的。
默認情況下 ReentrantLock 和 synchronized 都是非公平鎖。ReentrantLock 可以設置成公平鎖。
2、可重入鎖/不可重入鎖
可重入鎖指同一個線程可以再次獲得之前已經獲得的鎖,避免產生死鎖。
ReenTrantLock可以指定是公平鎖還是非公平鎖。而synchronized只能是非公平鎖。所謂的公平鎖就是先等待的線程先獲得鎖。
鎖的實現:
Synchronized是依賴於JVM實現的,而ReenTrantLock是JDK實現的
3、獨享鎖/共享鎖
獨享鎖(互斥鎖):同時只能有一個線程獲得鎖。比如,ReentrantLock 是互斥鎖,ReadWriteLock 中的寫鎖是互斥鎖。
共享鎖:可以有多個線程同時獲得鎖。比如,Semaphore、CountDownLatch 是共享鎖,ReadWriteLock 中的讀鎖是共享鎖。
4、樂觀鎖/悲觀鎖
5、分段鎖
5.1、線程不安全的HashMap
因為多線程環境下,使用Hashmap進行put操作會引起死循環,導致CPU利用率接近100%,所以在並發情況下不能使用HashMap。
5.2、效率低下的HashTable容器
HashTable容器使用synchronized來保證線程安全,但在線程競爭激烈的情況下HashTable的效率非常低下。因為當一個線程訪問HashTable的同步方法時,其他線程訪問HashTable的同步方法時,可能會進入阻塞或輪詢狀態。如線程1使用put進行添加元素,線程2不但不能使用put方法添加元素,並且也不能使用get方法來獲取元素,所以競爭越激烈效率越低。
5.3、ConcurrentHashMap分段鎖技術
ConcurrentHashMap是Java 5中支持高並發、高吞吐量的線程安全HashMap實現。
我們以ConcurrentHashMap來說一下分段鎖的含義以及設計思想,ConcurrentHashMap中的分段鎖稱為Segment,類似於HashMap(JDK7與JDK8中HashMap的實現)的結構,即內部擁有一個Entry數組,數組中的每個元素又是一個鏈表;同時又是一個ReentrantLock(Segment繼承了ReentrantLock)。
當需要put元素的時候,並不是對整個hashmap進行加鎖,而是先通過hashcode來知道他要放在哪一個分段中,然後對這個分段進行加鎖,所以當多線程put的時候,只要不是放在一個分段中,就實現了真正的並行的插入。
但是,在統計size的時候,可就是獲取hashmap全局信息的時候,就需要獲取所有的分段鎖才能統計。
分段鎖的設計目的是細化鎖的粒度,當操作不需要更新整個數組的時候,就僅僅針對數組中的一項進行加鎖操作。
6、Java多線程同步集合--並發庫高級應用
Java中鎖分類