摘要:下面我來簡單總結一下的核心要點底層結構是散列表數組鏈表紅黑樹,這一點和是一樣的。是將所有的方法進行同步,效率低下。而作為一個高并發的容器,它是通過部分鎖定算法來進行實現線程安全的。
前言
聲明,本文用的是jdk1.8
前面章節回顧:
Collection總覽
List集合就這么簡單【源碼剖析】
Map集合、散列表、紅黑樹介紹
HashMap就是這么簡單【源碼剖析】
LinkedHashMap就這么簡單【源碼剖析】
TreeMap就這么簡單【源碼剖析】
本篇主要講解ConCurrentHashMap~
看這篇文章之前最好是有點數據結構的基礎:
Java實現單向鏈表
棧和隊列就是這么簡單
二叉樹就這么簡單
當然了,如果講得有錯的地方還請大家多多包涵并不吝在評論去指正~
一、ConCurrentHashMap剖析ConCurrentHashMap在初學的時候反正我是沒有接觸過的,不知道你們接觸過了沒有~
這個類聽得也挺少的,在集合中是比較復雜的一個類了,它涉及到了一些多線程的知識點。
不了解或忘記多線程知識點的同學也不要怕,哪兒用到了多線程的知識點,我都會簡單介紹一下,并給出對應的資料去閱讀的~
好了,我們就來開始吧~
1.1初識ConCurrentHashMapConCurrentHashMap的底層是:散列表+紅黑樹,與HashMap是一樣的。
從前面的章節我們也可以發現:最快了解一下類是干嘛的,我們看源碼的頂部注釋就可以了!
我簡單翻譯了一下頂部的注釋(我英文水平渣,如果有錯的地方請多多包涵~歡迎在評論區下指正)
根據上面注釋我們可以簡單總結:
JDK1.8底層是散列表+紅黑樹
ConCurrentHashMap支持高并發的訪問和更新,它是線程安全的
檢索操作不用加鎖,get方法是非阻塞的
key和value都不允許為null
1.2JDK1.7底層實現上面指明的是JDK1.8底層是:散列表+紅黑樹,也就意味著,JDK1.7的底層跟JDK1.8是不同的~
JDK1.7的底層是:segments+HashEntry數組:
圖來源:https://blog.csdn.net/panweiw...
Segment繼承了ReentrantLock,每個片段都有了一個鎖,叫做“鎖分段”
大概了解一下即可~
1.3有了Hashtable為啥需要ConCurrentHashMapHashtable是在每個方法上都加上了Synchronized完成同步,效率低下。
ConcurrentHashMap通過在部分加鎖和利用CAS算法來實現同步。
1.4CAS算法和volatile簡單介紹在看ConCurrentHashMap源碼之前,我們來簡單講講CAS算法和volatile關鍵字
CAS(比較與交換,Compare and swap) 是一種有名的無鎖算法
CAS有3個操作數
內存值V
舊的預期值A
要修改的新值B
當且僅當預期值A和內存值V相同時,將內存值V修改為B,否則什么都不做
當多個線程嘗試使用CAS同時更新同一個變量時,只有其中一個線程能更新變量的值(A和內存值V相同時,將內存值V修改為B),而其它線程都失敗,失敗的線程并不會被掛起,而是被告知這次競爭中失敗,并可以再次嘗試(否則什么都不做)
看了上面的描述應該就很容易理解了,先比較是否相等,如果相等則替換(CAS算法)
參考資料:
CAS優秀博文:https://www.cnblogs.com/exceptioneye/p/5373498.html
CAS優秀博文:https://www.cnblogs.com/549294286/p/3766717.html
接下來我們看看volatile關鍵字,在初學的時候也很少使用到volatile這個關鍵字。反正我沒用到,而又經常在看Java相關面試題的時候看到它,覺得是一個挺神秘又很難的一個關鍵字。其實不然,還是挺容易理解的~
volatile經典總結:volatile僅僅用來保證該變量對所有線程的可見性,但不保證原子性
我們將其拆開來解釋一下:
保證該變量對所有線程的可見性
在多線程的環境下:當這個變量修改時,所有的線程都會知道該變量被修改了,也就是所謂的“可見性”
不保證原子性
修改變量(賦值)實質上是在JVM中分了好幾步,而在這幾步內(從裝載變量到修改),它是不安全的。
如果沒看懂或者想要深入了解其原理和可參考下列博文:
http://www.cnblogs.com/Mainz/p/3556430.html
https://www.cnblogs.com/Mainz/p/3546347.html
http://www.dataguru.cn/java-865024-1-1.html
1.5ConCurrentHashMap域域對象有這么幾個:
我們來簡單看一下他們是什么東東:
初次閱讀完之后,有的屬性我也不太清楚它是干什么的,在繼續閱讀之后可能就明朗了~
1.6ConCurrentHashMap構造方法ConcurrentHashMap的構造方法有5個:
具體的實現是這樣子的:
可以發現,在構造方法中有幾處都調用了tableSizeFor(),我們來看一下他是干什么的:
點進去之后發現,啊,原來我看過這個方法,在HashMap的時候.....
它就是用來獲取大于參數且最接近2的整次冪的數...
賦值給sizeCtl屬性也就說明了:這是下次擴容的大小~
1.7put方法終于來到了最核心的方法之一:put方法啦~~~~
我們先來整體看一下put方法干了什么事:
接下來,我們來看看初始化散列表的時候干了什么事:initTable()
只讓一個線程對散列表進行初始化!
1.8get方法從頂部注釋我們可以讀到,get方法是不用加鎖的,是非阻塞的。
我們可以發現,Node節點是重寫的,設置了volatile關鍵字修飾,致使它每次獲取的都是最新設置的值
二、總結上面簡單介紹了ConcurrentHashMap的核心知識,還有很多知識點都沒有提及到,作者的水平也不能將其弄懂~~有興趣進入的同學可到下面的鏈接繼續學習。
下面我來簡單總結一下ConcurrentHashMap的核心要點:
底層結構是散列表(數組+鏈表)+紅黑樹,這一點和HashMap是一樣的。
Hashtable是將所有的方法進行同步,效率低下。而ConcurrentHashMap作為一個高并發的容器,它是通過部分鎖定+CAS算法來進行實現線程安全的。CAS算法也可以認為是樂觀鎖的一種~
在高并發環境下,統計數據(計算size...等等)其實是無意義的,因為在下一時刻size值就變化了。
get方法是非阻塞,無鎖的。重寫Node類,通過volatile修飾next來實現每次獲取都是最新設置的值
ConcurrentHashMap的key和Value都不能為null
參考資料:
https://blog.csdn.net/u010723709/article/details/48007881
https://blog.csdn.net/melod_bc/article/details/54150679
https://blog.csdn.net/panweiwei1994/article/details/78897275
https://www.jianshu.com/p/e694f1e868ec
明天要是無意外的話,可能會寫Set集合,敬請期待哦~~~~
文章的目錄導航:https://zhongfucheng.bitcron.com/post/shou-ji/wen-zhang-dao-hang
如果文章有錯的地方歡迎指正,大家互相交流。習慣在微信看技術文章,想要獲取更多的Java資源的同學,可以關注微信公眾號:Java3y。為了大家方便,剛新建了一下qq群:742919422,大家也可以去交流交流。謝謝支持了!希望能多介紹給其他有需要的朋友
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69054.html
摘要:而在集合中,值僅僅是一個對象罷了該對象對本身而言是無用的。將這篇文章作為集合的總結篇,但覺得沒什么好寫就回答一些面試題去了,找了一會面試題又覺得不夠系統。 前言 聲明,本文用的是jdk1.8 花了一個星期,把Java容器核心的知識過了一遍,感覺集合已經無所畏懼了!!(哈哈哈....),現在來總結一下吧~~ 回顧目錄: Collection總覽 List集合就這么簡單【源碼剖析】 Ma...
摘要:下面總結一下集合常用的三個子類吧無序,允許為,底層是散列表紅黑樹,非線程同步有序,不允許為,底層是紅黑樹非線程同步迭代有序,允許為,底層是雙向鏈表,非線程同步從結論而言我們就可以根據自己的實際情況來使用了。 前言 聲明,本文用的是jdk1.8 前面章節回顧: Collection總覽 List集合就這么簡單【源碼剖析】 Map集合、散列表、紅黑樹介紹 HashMap就是這么簡單【源碼...
摘要:表示的是兩個,當其中任意一個計算完并發編程之是線程安全并且高效的,在并發編程中經常可見它的使用,在開始分析它的高并發實現機制前,先講講廢話,看看它是如何被引入的。電商秒殺和搶購,是兩個比較典型的互聯網高并發場景。 干貨:深度剖析分布式搜索引擎設計 分布式,高可用,和機器學習一樣,最近幾年被提及得最多的名詞,聽名字多牛逼,來,我們一步一步來擊破前兩個名詞,今天我們首先來說說分布式。 探究...
閱讀 3616·2021-11-24 10:22
閱讀 3686·2021-11-22 09:34
閱讀 2480·2021-11-15 11:39
閱讀 1528·2021-10-14 09:42
閱讀 3662·2021-10-08 10:04
閱讀 1553·2019-08-30 15:52
閱讀 847·2019-08-30 13:49
閱讀 3015·2019-08-30 11:21