Java多线程之并发容器(五)
1.hashtable和vector 它們是支持并發操作的并發容器,hashtable只不過是在hashmap的基礎上,所有的方法上都加上synchronized關鍵字,vector在ArrayList的基礎上,所有的方法上都加上synchronized關鍵字來達到同步的目的。 ?
2.Collections中的方法  這些方法實現起來也非常簡單,就是包裝類,把集合包裝起來,重寫每個方法,在每個重寫方法中加入一層鎖,達到同步的目的,這算不上是什么高超的技巧。 ?
3.ConcurrentHashMap
HashTable容器在競爭激烈的并發環境下表現出效率低下的原因,是因為所有訪問HashTable的線程都必須競爭同一把鎖,那假如容器里有多把鎖,每一把鎖用于鎖容器其中一部分數據,那么當多線程訪問容器里不同數據段的數據時,線程間就不會存在鎖競爭,從而可以有效的提高并發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術。
首先將數據分成一段一段的存儲,然后給每一段數據配一把鎖,當一個線程占用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。
有些方法需要跨段,比如size()和containsValue(),它們可能需要鎖定整個表而而不僅僅是某個段,這需要按順序鎖定所有段,操作完畢后,又按順序釋放所有段的鎖。這里“按順序”是很重要的,否則極有可能出現死鎖。
ConcurrentHashMap是由Segment數組和HashEntry數組組成。Segment是一種可重入鎖ReentrantLock,在ConcurrentHashMap里扮演鎖的角色,HashEntry則用于存儲鍵值對數據。
一個ConcurrentHashMap里包含一個Segment數組,是一種鏈表結構, 一個Segment里包含一個HashEntry數組,每個HashEntry是一個鏈表結構的元素。
每個Segment守護著一個HashEntry數組里的元素,當對HashEntry數組的數據進行修改時,必須首先獲得它對應的Segment鎖。
應用場景
當有一個大數組時需要在多個線程共享時就可以考慮是否把它給分層多個節點了,避免大鎖。并可以考慮通過hash算法進行一些模塊定位。
?
4.CopyOnWrite容器
CopyOnWrite容器也叫cow容器。如英文,它是一個寫是復制的容器。
當我們往一個容器添加元素的時候,不直接往當前容器添加,而是先將當前容器進行Copy,復制出一個新的容器,然后新的容器里添加元素,添加完元素之后,再將原容器的引用指向新的容器。這樣做的好處是我們可以對CopyOnWrite容器進行并發的讀,而不需要加鎖,因為當前容器不會添加任何元素。所以CopyOnWrite容器也是一種讀寫分離的思想,讀和寫不同的容器。
JDK中并沒有提供CopyOnWriteMap,我們可以參考CopyOnWriteArrayList來實現一個:
import java.util.Collection; import java.util.Map; import java.util.Set;public class CopyOnWriteMap<K, V> implements Map<K, V>, Cloneable {private volatile Map<K, V> internalMap;public CopyOnWriteMap() {internalMap = new HashMap<K, V>();}public V put(K key, V value) {synchronized (this) {Map<K, V> newMap = new HashMap<K, V>(internalMap);V val = newMap.put(key, value);internalMap = newMap;return val;}}public V get(Object key) {return internalMap.get(key);}public void putAll(Map<? extends K, ? extends V> newData) {synchronized (this) {Map<K, V> newMap = new HashMap<K, V>(internalMap);newMap.putAll(newData);internalMap = newMap;}} }實現很簡單,只要了解了CopyOnWrite機制,我們可以實現各種CopyOnWrite容器,并且在不同的應用場景中使用。
總結
以上是生活随笔為你收集整理的Java多线程之并发容器(五)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java多线程之迭代器问题(四)
- 下一篇: java美元兑换,(Java实现) 美元