concurrenthashmap是什么锁_多线程为什么要用ConcurrentHashMap
今天我們要說的是關于集合的問題,實際上跟鎖也有一定的關系,讓我們來一起看看吧。
一、簡介
1、是什么
ConcurrentHashMap是Java5中新增加的一個線程安全的Map集合,可以用來替代HashTable。對于ConcurrentHashMap是如何提高其效率的,可能大多人只是知道它使用了多個鎖代替HashTable中的單個鎖,也就是鎖分離技術(Lock Stripping)。
2、為什么
為什么不用HashMap
hashmap本質數據加鏈表。根據key取得hash值,然后計算出數組下標,如果多個key對應到同一個下標,就用鏈表串起來,新插入的在前面。而且hashmap在單線程情況下效率較高。
但是在多線程環境下,使用Hashmap進行put操作會引起死循環,導致CPU利用率接近100%,所以在并發情況下不能使用HashMap。
為什么不用HashTable
HashTable容器使用synchronized來保證線程安全,但在線程競爭激烈的情況下HashTable的效率非常低下。因為當一個線程訪問HashTable的同步方法時,其他線程訪問HashTable的同步方法時,可能會進入阻塞或輪詢狀態。如線程1使用put進行添加元素,線程2不但不能使用put方法添加元素,并且也不能使用get方法來獲取元素,所以競爭越激烈效率越低。
為什么要用ConcurrentHashMap
HashTable容器在競爭激烈的并發環境下表現出效率低下的原因,是因為所有訪問HashTable的線程都必須競爭同一把鎖,那假如容器里有多把鎖,每一把鎖用于鎖容器其中一部分數據,那么當多線程訪問容器里不同數據段的數據時,線程間就不會存在鎖競爭,從而可以有效的提高并發訪問效率,這就是ConcurrentHashMap所使用的鎖分段技術,首先將數據分成一段一段的存儲,然后給每一段數據配一把鎖,當一個線程占用鎖訪問其中一個段數據的時候,其他段的數據也能被其他線程訪問。
二、深入解析
1、結構圖解析
ConcurrentHashMap和Hashtable主要區別就是圍繞著鎖的粒度以及如何鎖,可以簡單理解成把一個大的HashTable分解成多個,形成了鎖分離。而Hashtable的實現方式是—鎖整個hash表
從圖中可以看到,ConcurrentHashMap內部分為很多個Segment,每一個Segment擁有一把鎖,然后每個Segment(繼承ReentrantLock)下面包含很多個HashEntry列表數組。對于一個key,需要經過三次(為什么要hash三次下文會詳細講解)hash操作,才能最終定位這個元素的位置,這三次hash分別為:
對于一個key,先進行一次hash操作,得到hash值h1,也即h1 = hash1(key);
將得到的h1的高幾位進行第二次hash,得到hash值h2,也即h2 = hash2(h1高幾位),通過h2能夠確定該元素的放在哪個Segment;
將得到的h1進行第三次hash,得到hash值h3,也即h3 = hash3(h1),通過h3能夠確定該元素放置在哪個HashEntry。
2、實現原理
ConcurrentHashMap把Map分成了N個Segment(默認16),其中Segment是線程同步的,相當于分成了N個Hashtable。當實現Put方法時,在key值經過正常的hash后,還要再經過一次segmentForHash算法,用來分配具體防盜哪個Segment。后來的線程如果經過計算也是放在這個Segment下,則需要先獲取鎖,如果計算得出應該放在其他的Segment,則正常執行,不會影響效率,以此實現線程安全。ConcurrentHashMap使用鎖分離技術,只要多個修改操作不發生在同一個Segment上,它們就可以并發進行。
有些方法需要跨段,比如size()和containsValue(),需要鎖定整個表而而不僅僅是某個段,這需要按順序鎖定所有段,操作完畢后,又按順序釋放所有段的鎖。這里“按順序”是很重要的,否則極有可能出現死鎖,在ConcurrentHashMap內部,段數組是final的,并且其成員變量實際上也是final的,但是,僅僅是將數組聲明為final的并不保證數組成員也是final的,這需要實現上的保證。這可以確保不會出現死鎖,因為獲得鎖的順序是固定的。
3、源碼詳解
這里不再細說,網上有很多。推薦Java并發包學習八]深度剖析ConcurrentHashMap
總結:
這個類其實在我們項目中的緩存使用到了,利用ConcurrentHashMap來存放一些常用的信息,由于是在并發的情況下使用,考慮到性能的問題,優先選用ConcurrentHashMap類。不過我建議大家還是要多看看源碼,從中會受益很多。
總結
以上是生活随笔為你收集整理的concurrenthashmap是什么锁_多线程为什么要用ConcurrentHashMap的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自动给文本框输入值_Dynamo for
- 下一篇: avue 文字点击 弹窗_经验 | UI