[集合]线程安全的HashMap
一、一般模式下線程安全的HashMap
默認(rèn)情況常用的HashMap都是線程不安全的,在多線程的環(huán)境下使用,常常會造成不可預(yù)知的,莫名其妙的錯誤。那么,我們?nèi)绾螌崿F(xiàn)一個線程安全的HashMap呢?其中一個可行的方式是使用Collectons.synchronizedMap() 方法來包裝我們的HashMap。如下:
Map<String, String> map = Collections.synchronizedMap(new HashMap<String,String>());Collections.synchronizedMap()會生成一個SynchronizedMap,它使用委托模式,將自己HashMap相關(guān)的功能交給傳入HashMap實現(xiàn),二自己負(fù)責(zé)線程安全的相關(guān)實現(xiàn),下面看看 SynchronizedMap的定義: private static class SynchronizedMap<K,V>implements Map<K,V>, Serializable {private static final long serialVersionUID = 1978198479659022715L;private final Map<K,V> m; // Backing Map// 使用 mutex 實心對 map 的互斥操作final Object mutex; // Object on which to synchronize SynchronizedMap(Map<K,V> m) {this.m = Objects.requireNonNull(m);mutex = this;}
如在代碼中看到的,所有對Map的操作都需要用 這個 mutex? 來同步,以實現(xiàn)線程安全。比如說下面這些常見的對HashMap的操作方法:
public boolean containsKey(Object key) {synchronized (mutex) {return m.containsKey(key);}}public boolean containsValue(Object value) {synchronized (mutex) {return m.containsValue(value);}}public V get(Object key) {synchronized (mutex) {return m.get(key);}}除了以上看到的方法之外,其他的Map相關(guān)的方法有類似的操作。雖然這個包裝的Map可以實現(xiàn)線程安全的要求,但是,它在多線程環(huán)境下的性能表現(xiàn)并不是很好,無論是對Map的讀取還是寫入,偶數(shù)需要獲得 mutex 的同步鎖,這會導(dǎo)致所有對Map的安全操作也會進入等待狀態(tài),知道m(xù)utex可用。 如果并發(fā)級別不高,那么這個 包裝的Map可以基本滿足要求,但是在搞并發(fā)的環(huán)境中,我們需要尋找新的解決方案。 ——---> 那就是我們的 ConcurrentHashMap.
?二、提高"鎖"性能的策略
1. 減少鎖的持有時間
只在必要時進行同步,減少鎖的持有時間。比如說在一個方法中只有一個變量需要同步,那么就沒有必要對這整個方法都進行同步,而只需要同步這個變量即可。
// 無謂的加鎖時間public synchronied void syncMethod() {othrerMethod();mutexMethod();otherMethod();}// 正確的加鎖時間public void syncMethod() {othrerMethod();synchronied(this){mutexMethod();}otherMethod();}?
2.? 減小鎖的粒度
在獲取全局信息方法不頻繁的時候,通過減小鎖的粒度可以搞系統(tǒng)的吞吐量。
3. 讀寫分離鎖替換獨占鎖
在讀都寫少的情況下,使用讀寫分離鎖,多線程讀時不阻塞,而只對寫線程進行同步。
4. 鎖分離
對不同功能的鎖進行不同的鎖策略。
5. 鎖粗化
系統(tǒng)對于"鎖"的調(diào)度也是需要性能消耗的,又是我們可以適當(dāng)?shù)募哟箧i的范圍,比如說在循環(huán)中盡量減少對鎖的請求和釋放,而是在得到鎖的情況,一次性把問題解決。
?
轉(zhuǎn)載于:https://www.cnblogs.com/ytuan996/p/10585633.html
總結(jié)
以上是生活随笔為你收集整理的[集合]线程安全的HashMap的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python注释缩进不得当导致Inden
- 下一篇: UIButton设置圆角和边框及边框颜色