HashMap與ConcurrentHashMap的區別
阿新 • • 發佈:2018-08-18
http trac net base 數據 概念 帶來 fill tools
ConcurrentHashMap中默認是把segments初始化為長度為16的數組。
從JDK1.2起,就有了HashMap,正如前一篇文章所說,HashMap不是線程安全的,因此多線程操作時需要格外小心。
在JDK1.5中,偉大的Doug Lea給我們帶來了concurrent包,從此Map也有安全的了。
ConcurrentHashMap具體是怎麽實現線程安全的呢,肯定不可能是每個方法加synchronized,那樣就變成了HashTable。
從ConcurrentHashMap代碼中可以看出,它引入了一個“分段鎖”的概念,具體可以理解為把一個大的Map拆分成N個小的HashTable,根據key.hashCode()來決定把key放到哪個HashTable中。
在ConcurrentHashMap中,就是把Map分成了N個Segment,put和get的時候,都是現根據key.hashCode()算出放到哪個Segment中:
測試程序:
[java] view plain copy
- import java.util.concurrent.ConcurrentHashMap;
- public class ConcurrentHashMapTest {
- private static ConcurrentHashMap<Integer, Integer> map = new ConcurrentHashMap<Integer, Integer>();
- public static void main(String[] args) {
- new Thread("Thread1"){
- @Override
- public void run() {
- map.put(3, 33);
- }
- };
- new Thread("Thread2"){
- @Override
- public void run() {
- map.put(4, 44);
- }
- };
- new Thread("Thread3"){
- @Override
- public void run() {
- map.put(7, 77);
- }
- };
- System.out.println(map);
- }
- }
ConcurrentHashMap中默認是把segments初始化為長度為16的數組。
根據ConcurrentHashMap.segmentFor的算法,3、4對應的Segment都是segments[1],7對應的Segment是segments[12]。
(1)Thread1和Thread2先後進入Segment.put方法時,Thread1會首先獲取到鎖,可以進入,而Thread2則會阻塞在鎖上:
(2)切換到Thread3,也走到Segment.put方法,因為7所存儲的Segment和3、4不同,因此,不會阻塞在lock():
以上就是ConcurrentHashMap的工作機制,通過把整個Map分為N個Segment(類似HashTable),可以提供相同的線程安全,但是效率提升N倍,默認提升16倍。
HashMap與ConcurrentHashMap的區別