首页
/
每日頭條
/
生活
/
concurrent hashmap底層原理1.8
concurrent hashmap底層原理1.8
更新时间:2025-09-05 14:48:02
ConcurrentHashMap簡單介紹

相比HashMap而言,是多線程安全的,其底層數據與HashMap的數據結構相同。

JDK1.7之前

通過對多個數組分段鎖機制(Segment)來實現的加鎖,默認16個Segment,16個分段,每個Segment對應Node[]數組,每個Segment有一把鎖,也就是說對一個Segment裡的Node[]數組的不同的元素如果要put操作的話,其實都是要競争一個鎖,串行化來處理的。

這種情況下,如果某一時間,同時并發訪問同一個數組段,其最大并發度受段的個數限制,效率還是低。

JDK1.8後

實現原理摒棄了這種設計,做了鎖粒度的細化,一個大的數組,數組裡每個元素進行put操作,都是有一個不同的鎖,剛開始進行put的時候,如果當前位置為空,執行CAS操作設值。

如果兩個線程都是在數組[5]這個位置進行put,這個時候如果裡面的值不為null,對數組[5]這個位置進行put的時候,采取的是synchronized(f)加鎖,鎖住這個節點,隻讓一個線程來處理鍊表或紅黑樹。

final V putVal(K key, V value, boolean onlyIfAbsent) { if (key == null || value == null) throw new NullPointerException(); int hash = spread(key.hashCode()); int binCount = 0; for (Node<K,V>[] tab = table;;) { Node<K,V> f; int n, i, fh; if (tab == null || (n = tab.length) == 0) tab = initTable(); else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {//如果當前位置沒有值,就進入CAS操作,成功就結束 if (casTabAt(tab, i, null,new Node<K,V>(hash, key, value, null)))//多線程的時候不成功,進入下次for循環設值 break; // no lock when adding to empty bin } else if ((fh = f.hash) == MOVED) tab = helpTransfer(tab, f); else { V oldVal = null; synchronized (f) {//鎖住這個節點,隻讓一個線程來處理鍊表或紅黑樹 if (tabAt(tab, i) == f) { if (fh >= 0) { binCount = 1; for (Node<K,V> e = f;; binCount) { K ek; if (e.hash == hash && ((ek = e.key) == key || (ek != null && key.equals(ek)))) { oldVal = e.val; if (!onlyIfAbsent) e.val = value; break; } Node<K,V> pred = e; if ((e = e.next) == null) { pred.next = new Node<K,V>(hash, key, value, null); break; } } } else if (f instanceof TreeBin) { Node<K,V> p; binCount = 2; if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key, value)) != null) { oldVal = p.val; if (!onlyIfAbsent) p.val = value; } } } } if (binCount != 0) { if (binCount >= TREEIFY_THRESHOLD) treeifyBin(tab, i); if (oldVal != null) return oldVal; break; } } } addCount(1L, binCount); return null;

如何保證取值的安全?

如果是get(key)的時候,是基于Unsafe.getObjectVolatile(),volatile讀機制,來讀取數組裡的節點,而節點裡面的value也是加了volatile,盡可能給你保證說是讀到了其他線程修改的一個最新的值,但是不需要加鎖volatile V val;

Volatile底部實現原理,關注我,後面會講解。

ConcurrentHashMap和Hashtable的區别

主要體現在實現線程安全的方式上不同。

1、HashTable内部的方法基本都經過 synchronized 修飾。而synchronized關鍵字加鎖是對整個對象進行加鎖,也就是說在進行put等修改Hash表的操作時,鎖住了整個Hash表,從而使得其表現的效率低下。

concurrent hashmap底層原理1.8(底部鎖實現細節)1

2、ConcurrentHashMap主要從之前的分段加鎖機制優化到現在的鎖粒度的細化。

concurrent hashmap底層原理1.8(底部鎖實現細節)2

concurrent hashmap底層原理1.8(底部鎖實現細節)3

下篇開始講解List集合相關特性及原理。

,
Comments
Welcome to tft每日頭條 comments! Please keep conversations courteous and on-topic. To fosterproductive and respectful conversations, you may see comments from our Community Managers.
Sign up to post
Sort by
Show More Comments
推荐阅读
民事訴訟26條内容
民事訴訟26條内容
上一期小編向大家介紹了立案時應該去哪個法院告以及本人無法到場該怎麼辦。那麼,交完材料後需要等多久呢?訴訟費又該交多少呢?接下來小編将向大家詳細講解~5交完材料後需要等多久?材料齊全後,法院會當場立案受理,複雜一些的案件法院會在7日内通知你是...
2025-09-05
國家鐵路八縱八橫規劃圖
國家鐵路八縱八橫規劃圖
這是十六條屬于《中長期鐵路網規劃》中的高速鐵路主通道,由八條縱向通道和八條橫向通道組成,每條通道由多段線路組成,包括既有線和新建線路,大部分主通道設計時速為250-350公裡,簡稱為“八縱八橫”高速鐵路通道。“八縱”通道1縱:沿海通道,起于...
2025-09-05
e大概是多大
e大概是多大
e大概是多大?e大概是2.71828e作為數學常數,是自然對數函數的底數有時稱它為歐拉數,以瑞士數學家歐拉命名;也有個較鮮見的名字納皮爾常數,以紀念蘇格蘭數學家約翰·納皮爾引進對數它就像圓周率π和虛數單位i,e是數學中最重要的常數之一,現在...
2025-09-05
如何檢測點火線圈
如何檢測點火線圈
如何檢測點火線圈?外部檢驗目測點火線圈,若有絕緣蓋破裂或外殼碰裂,就會受潮而失去點火能力,應予以更換,今天小編就來說說關于如何檢測點火線圈?下面更多詳細答案一起來看看吧!如何檢測點火線圈外部檢驗。目測點火線圈,若有絕緣蓋破裂或外殼碰裂,就會...
2025-09-05
ps運行很卡是什麼原因
ps運行很卡是什麼原因
導讀ps現在越來越多的人在使用,設計師、攝影、自由愛好者等等等等,從以前的cs版本到如今的cc版本,每一代版本都會有很多人吐槽使用過程中卡頓,甚至是卡死的現象,到底是adobe公司開發的這個軟件(ps)有問題呢?還是我們的硬件設備(電腦)有...
2025-09-05
Copyright 2023-2025 - www.tftnews.com All Rights Reserved