JAVA絕對乾貨——List、Set、Map併發資料結構對比實現
JAVA併發資料結構對比實現
在對List、Set、Map併發應用場合,我們可以使用Collections的下面方法將非執行緒安全List、set、Map轉化為執行緒安全的。但是效率並不是最好的,JDK提供了專門的執行緒安全List與Set實現類,後面我們將討論下他們的具體實現。
一、CopyOnWriteArrayList與Vector實現討論
CopyOnWriteArrayList與Vector是兩個執行緒安全的List,ArrayList不是執行緒安全的。下面我們對比下這兩個執行緒安全List的實現方式有什麼不同,各有什麼優點與缺點。
1. CopyOnWriteArrayList get()方法實現如下圖
CopyOnWriteArrayList get方法沒有進行任何鎖。所以效率要高。
2. Vector的get方法實現如下:
Vector的get方法增加了鎖,所以對比兩者get方法的,可以說明CopeOnWriteArrayList讀取更高效。
3. 下面我們對比Vector與CopyOnWriteArrayList 在新增資料方面的實現方法對比。
Vector 的add()方法實現如下圖:
4. CopyOnWriteArrayList 的add()方法實現如下圖:
CopyOnWriteArrayList add方法實現是先進行鎖定,再拷貝陣列,新增新元素後,再寫入,相比
併發寫多情況下建議用Vector,併發讀多的情況下建議用CopyOnWriteArrayList 。
二、併發Set
CopyOnWriteArraySet是實現了Set介面執行緒安全的。內部依賴於CopyOnWriteArrayList,因此適合讀多寫少的併發。
三、併發Map
JDK提供了高併發的Map實現ConcurrentHashMap.它的get是無鎖的,但是put是有鎖的。
四、併發Queue
ConcurrentLinkedQueue是一個適用於高併發場景下 佇列。它通過無鎖的方式,實現了高併發狀態下的高效能,通常它的效能好於BlockingQueue的典型實現ArrayBlockingQueue、LinkedBlockingQueue.
五、併發Deque
Deque是一個種雙端佇列,可以在頭部或尾部進行出隊入隊。
實現類有 ArrayDeque、LinkedBlockingDeque.
其中LinkedBlockingDeque是執行緒安全的,但是讀寫都加鎖,所以效率不是特別高。