在Java1.5以後,經過幾個併發容器類來改進同步容器類,同步容器類是經過將容器的狀態串行訪問,從而實現它們的線程安全的,這樣作會消弱了併發性,當多個線程併發的競爭容器鎖的時候,吞吐量會降低。那併發容器是爲多線程併發而設計的。那麼java1.5中添加了哪些併發容器?java
一、ConCurrentHashMap 來替代同步的HashMap 實現 安全
二、CopyOnWriteArrayList 是List的同步實現
三、Queue 和 BlockQueue 接口 多線程
四、ConCurrentLinkedQueue 一個併發優先級的隊列注意: java6中加入ConCurrentSkipListMap 和 ConCurrentSkipListSet 用來做爲同步的SortedMap 和SortedSet ..併發
2、ConCurrentHashMap 性能
咱們都知道同步容器類每當執行一個操做的時候都會持有一個鎖,若是同步容器中很是大,好比遍歷查找是否存某個對象,消耗時間很是長,可是這段時間不容許其餘線程訪問這個容器,這是一種糟糕是事情。 下載地址 ConCurrentHashMap 和HashMap 同樣都是一個hash表,可是ConCurrentHashMap與HashMap徹底使用不一樣的鎖策略。它能夠提供更好的併發性和伸縮性。在ConCurrentHashMap以前,是使用共用一個鎖,進行同步每個方法。而且嚴格的限制只有一個線程能同時訪問容器;而ConcurrentHashMap 使用了更加細粒度的鎖,-分離鎖( 詳情:ReentrantLock)這個鎖機制容許更深層的共享訪問,任何多線程能夠併發的讀操做訪問此容器,當且僅當只用一個線程能夠進行寫容器操做。這樣讀線程和寫線程均可以併發的訪問容器大大提升了吞吐量,也沒有怎麼損失單線程的性能。可是,在應用的需求是線程獨佔訪問枷鎖的時候,ConCurrentMap是沒法勝任的。ui
3、CopyOnWriteArrayListthis
CopyOnWriteArrayList 是 List容器的併發容器的替代品,一般它提供了更好的併發性,避免在容器迭代時候進行加鎖和複製。下面是一段源代碼spa
public E set(int index, E element) { 設計
final ReentrantLock lock = this.lock;
lock.lock();
try {
Object[] elements = getArray();
E oldValue = get(elements, index);
if (oldValue != element) {
int len = elements.length;
Object[] newElements = Arrays.copyOf(elements, len);
newElements[index] = element;
setArray(newElements);
} else {
// Not quite a no-op; ensures volatile write semantics
setArray(elements);
}
return oldValue;
} finally {
lock.unlock();
}
}
public E set(int index, E element) { final ReentrantLock lock = this.lock; lock.lock(); try { Object[] elements = getArray(); E oldValue = get(elements, index); if (oldValue != element) { int len = elements.length; Object[] newElements = Arrays.copyOf(elements, len); newElements[index] = element; setArray(newElements); } else { // Not quite a no-op; ensures volatile write semantics setArray(elements); } return oldValue; } finally { lock.unlock(); } }
在操做以前:lock.lock(); 而後 lock.unlock(); 釋放
/**
* {@inheritDoc}
*
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
return get(getArray(), index);
}
/** * {@inheritDoc} * * @throws IndexOutOfBoundsException {@inheritDoc} */ public E get(int index) { return get(getArray(), index); }
讀取不會加鎖和釋放鎖操做。