文章目錄
- 執行緒安全的List
- 執行緒安全的Set
- 執行緒安全的Map
我們都是知道像常用的ArrayList、LinkedList、hashSet、hashMap等都是執行緒不安全的集合,在多執行緒下可能會出現
并發修改例外:
ConcurrentModificationException,那沒如何來使用執行緒安全的集合呢?
vector和
HashTable 就不說了,因為他雖然是執行緒安全的集合,但是實作方式是在底層方法上全都加了
Synchronized來修飾的,效率低,
執行緒安全的List
Collections工具類提供了創建執行緒安全的List的方法:
List<String> list = Collections.synchronizedList(new ArrayList<> ());
不過這里我們重點說JUC下的CopyOnWriteArrayList
CopyOnWrite:寫入時復制思想,簡稱COW,是計算機程式設計領域的一種優化策略
創建方式:
List<String> list = new CopyOnWriteArrayList<>();
實作原理:
我們先閱讀其原始碼了解下它是如何實作的,以下代碼是向CopyOnWriteArrayList中add方法的實作(向CopyOnWriteArrayList里添加元素),可以發現在添加的時候是加了ReentrantLock 鎖,并且是先Copy出副本添加,最后再賦值,
/**
* Appends the specified element to the end of this list.
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len + 1);
newElements[len] = e;
setArray(newElements);
return true;
} finally {
lock.unlock();
}
}
讀的時候不需要加鎖,如果讀的時候有多個執行緒正在向CopyOnWriteArrayList添加資料,讀還是會讀到舊的資料,因為寫的時候不會鎖住舊的List,
public E get(int index) {
return get(getArray(), index);
}
執行緒安全的Set
Collections工具類提供了創建執行緒安全的Set的方法:
Set<String> set = Collections.synchronizedSet(new HashSet<>());
同上,JUC下有Set<String> set = new CopyOnWriteArraySet<>();
這里額外說下,hashSet 底層是什么?
其實hashSet底層就是用的hashMap的Key,而value就是一個用static和final修飾的object不變值,

執行緒安全的Map
Collections工具類提供了創建執行緒安全的Map的方法:
Collections.synchronizedMap(new HashMap<>());
這里可不能同上了,因為JDK并沒有給我們提供“CopyOnWriteMap”,而是提供了一個ConcurrentHashMap,
Map<String, String> map = new ConcurrentHashMap<>();
jdk1.7中ConcurrentHashMap相對于HashMap其實多了一個Segment 的的角色,它其實是一種可重入鎖(ReentrantLock),在ConcurrentHashMap里扮演鎖的角色,
jdk1.8中放棄了Segment臃腫的分段鎖設計,取而代之的是采用Node + CAS + Synchronized來保證并發安全進行實作,
上一篇:JUC并發編程-8鎖現象
下一篇:JUC中常用的三大輔助類
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/237587.html
標籤:其他
上一篇:西瓜視頻穩定性治理體系建設一:Tailor 原理及實踐
下一篇:XSS和SQL注入
