ava並發編程:並發容器之ConcurrentHashMap
下面這部分內容轉載自:
http://www.haogongju.net/art/2350374
JDK5中添加了新的concurrent包,相對同步容器而言,並發容器通過一些機制改進了並發效能。因為同步容器將所有對容器狀態的訪問都
序列化了,這樣保證了線程的安全性,所以這種方法的代價就是嚴重降低了並發性,當多個線程競爭容器時,輸送量嚴重降低。因此Java5.0開
始針對多線程並發訪問設計,提供了並發效能較好的並發容器,引入了java.util.concurrent包。與Vector和Hashtable、
Collections.synchronizedXxx()同步容器等相比,util.concurrent中引入的並發容器主要解決了兩個問題:
1)根據具體情境進行設計,盡量避免synchronized,提供並發性。
2)定義了一些並發安全的複合操作,並且保證並發環境下的迭代操作不會出錯。
util.concurrent中容器在迭代時,可以不封裝在synchronized中,可以保證不拋異常,但是未必每次看到的都是"最新的、當前的"資料。
下面是對並發容器的簡單介紹:
ConcurrentHashMap代替同步的Map(Collections.synchronized(new HashMap())),眾所周知,HashMap是根據散列值分段儲存的,同步Map在同步的時候鎖住了所有的段,而ConcurrentHashMap加鎖的時候根據散列值鎖住了散列值鎖對應的那段,因此提高了並發效能。ConcurrentHashMap也增加了對常用複合操作的支援,比如"若沒有則添加":putIfAbsent(),替換:replace()。這2個操作都是原子操作。
CopyOnWriteArrayList和CopyOnWriteArraySet分別代替List和Set,主要是在遍曆操作為主的情況下來代替同步的List和同步的Set,這也就是上面所述的思路:迭代過程要保證不出錯,除了加鎖,另外一種方法就是"複製"容器物件。
ConcurrentLinkedQuerue是一個先進先出的隊列。它是非阻塞隊列。
ConcurrentSkipListMap可以在高效並發中替代SoredMap(例如用Collections.synchronzedMap封裝的TreeMap)。
ConcurrentSkipListSet可以在高效並發中替代SoredSet(例如用Collections.synchronzedSet封裝的TreeMap)。
本篇文章著重講解2個並發容器:ConcurrentHashMap和CopyOnWriteArrayList其中的ConcurrentHashMap,CopyOnWriteArrayList在下一篇文章中講述。
原文連結:http://www.iteye.com/topic/1103980
大家都知道HashMap是非安全執行緒的,Hashtable是安全執行緒的,但是由於Hashtable是採用synchronized進行同步,相當於所有線程進行讀寫時都去競爭一把鎖,導致效率非常低下。
ConcurrentHashMap可以做到讀取資料不加鎖,並且其內部的結構可以讓其在進行寫操作的時候能夠將鎖的粒度保持地盡量地小,不用對整個ConcurrentHashMap加鎖。 ConcurrentHashMap的內部結構
ConcurrentHashMap為了提高本身的並發能力,在內部採用了一個叫做Segment的結構,一個Segment其實就是一個類Hash Table的結構,Segment內部維護了一個鏈表數組,我們用下面這一幅圖來看下ConcurrentHashMap的內部結構:
從上面的結構我們可以瞭解到,ConcurrentHashMap定位一個元素的過程需要進行兩次Hash操作,第一次Hash定位到Segment,第二次Hash定位到元素所在的鏈表的頭部,因此,這一種結構的帶來的副作用是Hash的過程要比普通的HashMap要長,但是帶來的好處是寫操作的時候可以只對元素所在的Segment進行加鎖即可,不會影響到其他的Segment,這樣,在最理想的情況下,ConcurrentHashMap可以最高同時支援Segment數量大小的寫操作(剛好這些寫操作都非常平均地分布在所有的Segment上),所以,通過這一種結構,ConcurrentHashMap的並發能力可以大大的提高。 Segment
我們再來具體瞭解一下Segment的資料結構:
1 2 3 4 5 6 7 |
static final class Segment<K,V> extends ReentrantLock implements Serializable { transient volatile int count; transient int modCount; transient int threshold; transient volatile |