精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

深入淺出ConcurrentHashMap內部實現

開發 前端
ConcurrentHashMap可以說是并發設計的典范,在JDK8中,ConcurrentHashMap可以說是再一次脫胎換骨,全新的架構和實現帶來了飛一般的體驗(JDK7中的ConcurrentHashMap還是采用比較骨板的segment實現的),細細品讀,還是有不少的收獲。

ConcurrentHashMap可以說是目前使用最多的并發數據結構之一,作為如此核心的基本組件,不僅僅要滿足我們功能的需求,更要滿足性能的需求。而實現一個高性能的線程安全的HashMap也絕非易事。

ConcurrentHashMap作為JDK8的內部實現,一個成功的典范,有著諸多可以讓我們學習和致敬的地方。

我全局在項目中搜索這個類的時候,發現大量項目代碼和源碼都用到了,為什么他會這么吃香呢?到底是道德的....呸。

下面我們就來扒一扒,ConcurrentHashMap的內部實現,來體會一下它的精妙之處吧!

ConcurrentHashMap的內部數據結構

在JDK8中, ConcurrentHashMap的內部實現發生了天翻地覆的變化。這里依據JDK8,來介紹一下ConcurrentHashMap的內部實現。

從靜態數據結構上說,ConcurrentHashMap包含以下內容:

int sizeCtl

這是一個多功能的字段,可以用來記錄參與Map擴展的線程數量,也用來記錄新的table的擴容閾值

CounterCell[] counterCells

用來記錄元素的個數,這是一個數組,使用數組來記錄,是因為避免多線程競爭時,可能產生的沖突。使用了數組,那么多個線程同時修改數量時,極有可能實際操作數組中不同的單元,從而減少競爭。

Node<K,V>[] table

實際存放Map內容的地方,一個map實際上就是一個Node數組,每個Node里包含了key和value的信息。

Node<K,V>[] nextTable

當table需要擴充時,會把新的數據填充到nextTable中,也就是說nextTable是擴充后的Map。

以上就是ConcurrentHashMap的核心元素,其中最值得注意的便是Node,Node并非想象中如此簡單,下面的圖展示了Node的類族結構:

可以看到,在Map中的Node并非簡單的Node對象,實際上,它有可能是Node對象,也有可能是一個Treebin或者ForwardingNode。

那什么時候是Node,什么時候是TreeBin,什么時候又是一個ForwardingNode呢?

其實在絕大部分場景中,使用的依然是Node,從Node數據結構中,不難看出,Node其實是一個鏈表,也就是說,一個正常的Map可能是長這樣的:

上圖中,綠色部分表示Node數組,里面的元素是Node,也就是鏈表的頭部,當兩個元素在數據中的位置發生沖突時,就將它們通過鏈表的形式,放在一個槽位中。

當數組槽位對應的是一個鏈表時,在一個鏈表中查找key只能使用簡單的遍歷,這在數據不多時,還是可以接受的,當沖突數據比較多少,這種簡單的遍歷就有點慢了。

因此,在具體實現中,當鏈表的長度大于等于8時,會將鏈表樹狀化,也就是變成一顆紅黑樹。如下圖所示,其中一個槽位就變成了一顆樹,這就是TreeBin(在TreeBin中使用TreeNode構造整科樹)。

 

當數組容量快滿時,即超過75%的容量時,數組還需要進行擴容,在擴容過程中,如果老的數組已經完成了復制,那么就會將老數組中的元素使用ForwardingNode對象替代,表示當前槽位的數據已經處理了,不需要再處理了,這樣,當有多個線程同時參與擴容時,就不會沖突。

put()方法的實現

現在來看一下作為一個HashMap最為重要的方法put():

  • public V put(K key, V value)

它負責將給定的key和value對存入HashMap,它的工作主要有以下幾個步驟:

  1. 如果沒有初始化數組,則嘗試初始化數組
  2. 如果當前正在擴容,則參與幫助擴容(調用helpTransfer()方法)
  3. 將給定的key,value 放入對應的槽位
  4. 統計元素總數
  5. 觸發擴容操作

根據以上主要4個步驟,來依次詳細說明一下:

如果沒有初始化數組,則嘗試初始化數組

初始化數據會生成一個Node數組:

  1. Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n]; 

默認情況下,n為16。同時設置sizeCtl為·n - (n >>> 2); 這意味著sizeCtl為n的75%,表示Map的size,也就是說ConcurrentHashMap的負載因子是0.75。(為了避免沖突,Map的容量是數組的75%,超過這個閾值,就會擴容)

如果當前正在擴容,則參與幫助擴容

  1. else if ((fh = f.hash) == MOVED) 
  2.     tab = helpTransfer(tab, f); 

如果一個節點的hash是MOVE,則表示這是一個ForwardingNode,也就是當前正在擴容中,為了盡快完成擴容,當前線程就會參與到擴容的工作中,而不是等待擴容操作完成,如此緊密細致的操作,恰恰是ConcurrentHashMap高性能的原因。

而代碼中的f.hash==MOVE語義上等同于f instanceof ForwardingNode,但是使用整數相等的判斷的效率要遠遠高于instanceof,所以,這里也是一處對性能的極限優化。

將給定的key,value 放入對應的槽位

在大部分情況下,應該會走到這一步,也就是將key和value放入數組中。在這個操作中會使用大概如下操作:

  1. Node<K,V> f; 
  2. synchronized (f) { 
  3.      if(所在槽位是一個鏈表) 
  4.          插入鏈表 
  5.      else if(所在槽位是紅黑樹) 
  6.          插入樹 
  7.      if(鏈表長度大于8[TREEIFY_THRESHOLD]) 
  8.          將鏈表樹狀化 

可以看到,這使用了synchronized關鍵字,鎖住了Node對象。由于在絕大部分情況下,不同線程大概率會操作不同的Node,因此這里的競爭應該不會太大。

并且隨著數組規模越來越大,競爭的概率會越來越小,因此ConcurrentHashMap有了極好的并行性。

統計元素總數

為了有一個高性能的size()方法,ConcurrentHashMap使用了單獨的方法來統計元素總數,元素數量統計在CounterCell數組中:

  1. CounterCell[] counterCells; 
  2. @sun.misc.Contended static final class CounterCell { 
  3.     volatile long value; 
  4.     CounterCell(long x) { value = x; } 

CounterCell使用偽共享優化,具有很高的讀寫性能。counterCells中所有的成員的value相加,就是整個Map的大小。這里使用數組,也是為了防止沖突。

如果簡單使用一個變量,那么多線程累加一個計數器時,難免要有競爭,現在分散到一個數組中,這種競爭就小了很多,對并發就更加友好了。

累加的主要邏輯如下:

  1. if (as == null || (m = as.length - 1) < 0 || 
  2.     //不同線程映射到不同的數組元素,防止沖突 
  3.     (a = as[ThreadLocalRandom.getProbe() & m]) == null || 
  4.     //使用CAS直接增加對應的數據 
  5.     !(uncontended = 
  6.       U.compareAndSwapLong(a, CELLVALUE, v = a.value, v + x))) 
  7.     //如果有競爭,在這里會重試,如果競爭嚴重還會將CounterCell[]數組擴容,以減少競爭 

觸發擴容操作

最后,ConcurrentHashMap還會檢查是否需要擴容,它會檢查當前Map的大小是否超過了閾值,如果超過了,還會進行擴容。

ConcurrentHashMap的擴容過程非常巧妙,它并沒有完全打亂當前已有的元素位置,而是在數組擴容2倍后,將一半的元素移動到新的空間中。

所有的元素根據高位是否為1分為low節點和high節點:

  1. //n是數組長度,數組長度是2的冪次方,因此一定是100 1000 10000 100000這種二進制數字 
  2. //這里將low節點串一起, high節點串一起 
  3. if ((ph & n) == 0) 
  4.     ln = new Node<K,V>(ph, pk, pv, ln); 
  5. else 
  6.     hn = new Node<K,V>(ph, pk, pv, hn); 

接著,重新放置這些元素的位置:

  1. //low節點留在當前位置 
  2. setTabAt(nextTab, i, ln); 
  3. //high節點放到擴容后的新位置,新位置距離老位置n 
  4. setTabAt(nextTab, i + n, hn); 
  5. //擴容完成,用ForwardingNode填充 
  6. setTabAt(tab, i, fwd); 

下圖顯示了 從8擴充到16時的可能得一種擴容情況,注意,新的位置總是在老位置的后面n個槽位(n為原數組大小)

這樣做的好處是,每個元素的位置不需要重新計算,進行查找時,由于總是會對n-1(一定是一個類似于1111 11111 111111這樣的二進制數)按位與,因此,high類的節點自然就會出現在+n的位置上。

get()方法的實現

與put()方法相比,get()方法就比較簡單了。步驟如下:

  1. 根據hash值 得到對應的槽位 (n - 1) & h
  2. 如果當前槽位第一個元素key就和請求的一樣,直接返回
  3. 否則調用Node的find()方法查找
  4. 對于ForwardingNode 使用的是 ForwardingNode.find()
  5. 對于紅黑樹 使用的是TreeBin.find()
  6. 對于鏈表型的槽位,依次順序查找對應的key

寫在最后

ConcurrentHashMap可以說是并發設計的典范,在JDK8中,ConcurrentHashMap可以說是再一次脫胎換骨,全新的架構和實現帶來了飛一般的體驗(JDK7中的ConcurrentHashMap還是采用比較骨板的segment實現的),細細品讀,還是有不少的收獲。

他和HashMap的區別,優劣勢對比,這也是常考的考點,所以大家不管是為了了解、工作還是面試,都應該好好的熟悉一下。

多線程系列我會繼續更新,我是敖丙,你知道的越多,你不知道的越多,我們江湖見。

 

責任編輯:姜華 來源: 三太子敖丙
相關推薦

2021-03-16 08:54:35

AQSAbstractQueJava

2011-07-04 10:39:57

Web

2023-03-20 09:48:23

ReactJSX

2017-07-02 18:04:53

塊加密算法AES算法

2019-01-07 15:29:07

HadoopYarn架構調度器

2021-07-20 15:20:02

FlatBuffers阿里云Java

2012-05-21 10:06:26

FrameworkCocoa

2022-09-26 09:01:15

語言數據JavaScript

2019-11-11 14:51:19

Java數據結構Properties

2009-11-30 16:46:29

學習Linux

2018-11-09 16:24:25

物聯網云計算云系統

2022-11-09 08:06:15

GreatSQLMGR模式

2012-02-21 13:55:45

JavaScript

2022-10-31 09:00:24

Promise數組參數

2009-11-18 13:30:37

Oracle Sequ

2022-12-02 09:13:28

SeataAT模式

2019-12-04 10:13:58

Kubernetes存儲Docker

2022-01-11 07:52:22

CSS 技巧代碼重構

2025-03-27 09:38:35

2016-10-14 13:53:05

JavascriptDOMWeb
點贊
收藏

51CTO技術棧公眾號

日韩a级片在线观看| 日本中文字幕高清| 人人妻人人玩人人澡人人爽| 国产一区二区三区的电影 | 日韩欧美精品三级| 国产精品视频网站在线观看| 国产在线中文字幕| 韩日精品视频一区| 97精品国产91久久久久久| 亚洲欧美日本一区| 91精品在线免费视频| 婷婷久久综合九色国产成人| 亚洲v国产v在线观看| 免费av网站观看| 久久亚洲电影| 欧美福利在线观看| 国产亚洲精品久久久久久豆腐| 在线观看涩涩| 亚洲人成网站精品片在线观看| 国产精品jvid在线观看蜜臀| 婷婷色中文字幕| 欧美日韩性在线观看| 亚洲国产美女精品久久久久∴| 男女爱爱视频网站| 国产色a在线| 91女厕偷拍女厕偷拍高清| 亚洲综合成人婷婷小说| 自拍偷拍色综合| 免播放器亚洲| 久久久久久久久电影| 中文乱码字幕高清一区二区| 免费欧美激情| 日韩成人高清在线| 亚洲最大视频网| 成人1区2区| 91国产丝袜在线播放| 美女av免费在线观看| 91黄页在线观看| 亚洲国产你懂的| 久久综合亚洲精品| 国产精品刘玥久久一区| 国产精品久久久久久久浪潮网站| 91香蕉国产在线观看| 中文字幕免费播放| 麻豆亚洲精品| 日本精品视频在线播放| 欧美亚洲精品天堂| 国产精品入口| 55夜色66夜色国产精品视频| www日韩精品| 亚洲免费大片| 欧美影院在线播放| 91丝袜一区二区三区| 香蕉成人久久| 国产91在线播放| 手机在线看片1024| 奇米精品一区二区三区四区| 国产精品视频中文字幕91| 欧美成人一区二区视频| 麻豆91在线看| 91在线视频成人| 99在线观看精品视频| 国产大陆精品国产| 国产日韩欧美综合精品| 亚洲av成人精品日韩在线播放| 蜜桃av一区二区三区| 国产精品男女猛烈高潮激情| 又骚又黄的视频| 久久99日本精品| 亚洲xxxx在线| 视频一区二区免费| 国产拍欧美日韩视频二区| 亚洲一区二区免费视频软件合集 | 青青草原免费观看| 国语精品一区| 欧美在线视频网站| 亚洲精品一区二区二区| 国产一区欧美二区| 国产福利一区二区三区在线观看| 精人妻无码一区二区三区| 日韩高清在线一区| 91在线无精精品一区二区| 人妻精品一区一区三区蜜桃91| 蜜臀久久久久久久| 亚洲综合在线播放| 免费在线超碰| 综合久久综合久久| 久久国产精品视频在线观看| 日本综合久久| 日韩欧美一级二级三级久久久| 亚洲xxxx2d动漫1| 国产一区二区三区免费在线 | 精品国自产在线观看| 99久久精品免费看国产| 日本一区免费观看| fc2ppv国产精品久久| 精品国产91久久久久久老师| 欧美一级裸体视频| 国偷自产av一区二区三区| 一区二区在线视频| 国产大片中文字幕| 美女视频网站黄色亚洲| 国产乱码精品一区二区三区日韩精品| 国产色视频在线| 久久婷婷国产综合国色天香| 中文字幕の友人北条麻妃| 成人动漫一区| 欧美大片拔萝卜| 一本在线免费视频| 亚洲欧美日韩精品一区二区| 亚洲综合色av| caoporn国产精品免费视频| 亚洲国产精品一区二区久久恐怖片| 黄色一级片黄色| 国产精品天堂蜜av在线播放| 亚洲国产欧美自拍| 青青草原在线免费观看| 久久美女性网| 好吊妞www.84com只有这里才有精品| 日本激情一区二区| 国产精品成人免费| 人人爽人人av| 西野翔中文久久精品字幕| 欧美丰满少妇xxxxx做受| 国产一区二区在线视频聊天| 久久综合丝袜日本网| 人体内射精一区二区三区| 欧美高清一级片| 色偷偷888欧美精品久久久| 国产原创视频在线| caoporn国产一区二区| 少妇一晚三次一区二区三区| 亚洲国产aⅴ精品一区二区三区| 欧美一级片免费看| 久久久久久久麻豆| 看国产成人h片视频| 亚洲成人av动漫| 国产精品久久久久av电视剧| 亚洲欧美国产精品| 欧美亚韩一区二区三区| 99久久久无码国产精品| 中文字幕人妻熟女人妻洋洋| 日本精品在线观看| 欧美精品在线免费观看| 国产偷人妻精品一区二区在线| 成人免费视频视频| 日本天堂免费a| 欧美国产亚洲精品| 久久免费高清视频| 日韩中文字幕综合| 天天色 色综合| 久久精品老司机| 丝袜美腿亚洲色图| 亚洲蜜桃av| 外国成人毛片| 色婷婷久久一区二区| 91精品在线视频观看| 中文字幕人成不卡一区| 亚洲精品在线网址| 国产精品hd| 国产一区喷水| 欧美巨大丰满猛性社交| 亚洲欧美日韩在线一区| 日韩精选在线观看| 亚洲视频每日更新| 国产女人18毛片水真多18| 亚洲欧美日韩精品一区二区 | 亚洲av无码乱码在线观看性色 | 欧美大片日本大片免费观看| 免费网站观看www在线观| 成人精品视频一区二区三区| 少妇高潮喷水在线观看| 亚洲丝袜美腿一区| 国产欧美一区二区三区视频 | 久久影院视频免费| 亚洲五码在线观看视频| 草莓视频一区二区三区| 2019中文字幕全在线观看| 91sp网站在线观看入口| 日韩限制级电影在线观看| 日韩av电影网址| 国产精品天美传媒| 四虎永久免费观看| 日韩电影免费在线观看网站| 精品国产三级a∨在线| 久9re热视频这里只有精品| 国产91在线播放| 色女人在线视频| 亚洲视频欧洲视频| 精品久久久无码中文字幕| 欧美视频在线观看 亚洲欧| 女人18毛片毛片毛片毛片区二| 日韩中文字幕1| 青青草免费在线视频观看| 大香伊人久久精品一区二区| 国产国语videosex另类| 性xxxxfjsxxxxx欧美| 亚洲午夜色婷婷在线| 精品毛片在线观看| 91精品福利视频| 国产精品99精品| 中文字幕日本不卡| 久久只有这里有精品| 国产成人啪午夜精品网站男同| 日本大胆人体视频| 精品freesex老太交| 国产精品久久久久久免费观看| 18av在线视频| 一本色道久久综合狠狠躁篇怎么玩| 色屁屁影院www国产高清麻豆| 99久久国产综合精品色伊| 最新av免费在线观看| 久久99伊人| 国产成a人亚洲精v品在线观看| 成人av综合网| 成人欧美在线观看| 3d欧美精品动漫xxxx无尽| 77777少妇光屁股久久一区| 成人无遮挡免费网站视频在线观看| 在线电影欧美成精品| chinese国产精品| 精品国产乱码久久久久久婷婷 | 国产精品你懂的| 毛茸茸多毛bbb毛多视频| 国产乱色国产精品免费视频| 天堂在线资源视频| 可以看av的网站久久看| 99精品在线免费视频| 红桃视频欧美| 成人av在线不卡| 欧美成人tv| 午夜啪啪免费视频| 国产精品成人a在线观看| 视频在线99re| 欧美丝袜激情| 亚洲一区精彩视频| 欧美成人激情| 亚洲日本精品国产第一区| 精品日韩在线| 亚洲精品中文字幕乱码三区不卡| 激情综合五月| 亚洲精品欧美日韩| 日本一区二区三区播放| 亚洲xxx视频| 国产成人精品亚洲线观看| 超碰97人人人人人蜜桃| 91麻豆精品激情在线观看最新| 欧美一级大片在线观看| 久久久123| 57pao成人永久免费视频| 自拍偷拍亚洲视频| 国产99久久久欧美黑人| 最新日韩三级| 国产区亚洲区欧美区| vam成人资源在线观看| 91九色精品视频| 一区视频网站| 你懂的视频在线一区二区| 国产精品嫩模av在线| 亚洲国产欧美日韩| 99久久影视| 91午夜在线观看| 小嫩嫩精品导航| 91制片厂毛片| 国产精品99久久久久久宅男| 韩国av中国字幕| 久久精品综合网| 2017亚洲天堂| 洋洋成人永久网站入口| 在线能看的av| 欧美日韩一级二级| 亚洲国产www| 国产视频久久网| 久操视频在线播放| 国内免费久久久久久久久久久| 久久黄色美女电影| 亚洲97在线观看| 国产伊人久久| 国产精品乱子乱xxxx| 久操成人av| 国产一区一区三区| 亚洲作爱视频| 加勒比av中文字幕| 北条麻妃一区二区三区| 久久av无码精品人妻系列试探| 成人激情小说乱人伦| 娇妻被老王脔到高潮失禁视频| 99久久精品免费| 欧美肥妇bbwbbw| 五月天国产精品| 91亚洲国产成人久久精品麻豆| 在线精品视频免费播放| 国产视频在线一区| 亚洲热线99精品视频| 影院在线观看全集免费观看| 日本午夜在线亚洲.国产| 精品一区91| 色999五月色| 亚洲理论在线| 久久精品无码一区二区三区毛片| 青青草成人在线观看| 美女搡bbb又爽又猛又黄www| 国产亚洲va综合人人澡精品 | 国产精品一区二区av交换| 欧美 国产 精品| 久久久亚洲一区| 一起草在线视频| 亚洲综合色视频| 国产精品无码在线播放| 亚洲人成电影网站色www| 国产美女一区视频| 亚洲aⅴ日韩av电影在线观看| 日韩精品一区二区三区免费视频| 91观看网站| 日韩欧美精品一区| 老熟妇仑乱视频一区二区| 国产盗摄精品一区二区三区在线 | 久久久在线免费观看| 国产精成人品2018| 久久人人九九| 亚洲巨乳在线| 极品白嫩的小少妇| 一区二区久久久久| 999精品国产| 日韩一级黄色av| 欧美成人家庭影院| 日韩精品无码一区二区三区| 性8sex亚洲区入口| 国产偷人妻精品一区| 亚洲成a人片综合在线| 精品人妻无码一区二区| 中文字幕日韩在线观看| 91av一区| 视频一区二区三区免费观看| 乱码第一页成人| 久久久久久久久久久久久久久| 国产精品传媒视频| 亚洲最大成人av| 久久精品中文字幕一区| 国产私拍福利精品视频二区| 欧洲在线视频一区| 久久国产欧美| www.av天天| 欧美色窝79yyyycom| 18免费在线视频| 国产精品一区二区三区久久| 色婷婷色综合| 日韩成人精品视频在线观看| 中文字幕五月欧美| 99精品在线看| 欧美—级高清免费播放| 精品少妇一区| 精品99在线视频| 欧美激情一区在线观看| 亚洲无码精品在线播放| 久久这里只有精品99| 看亚洲a级一级毛片| 国产一区二区三区乱码| 99视频有精品| 波多野结衣大片| 久久综合伊人77777蜜臀| 777久久精品| 少妇无码av无码专区在线观看| 国模娜娜一区二区三区| 色哟哟一一国产精品| 欧美一卡2卡3卡4卡| av色在线观看| 久久一区二区精品| 看片的网站亚洲| 久久精品免费av| 亚洲视频专区在线| **国产精品| 欧美精品久久久久久久免费| 国产亚洲一区二区三区| 国产免费高清视频| 97在线观看视频| 久久国产亚洲| 国产情侣久久久久aⅴ免费| 色婷婷av一区二区三区之一色屋| 十九岁完整版在线观看好看云免费| 久久中文字幕在线| 久久精品色播| 日本黄大片一区二区三区| 亚洲精品网站在线观看| 日韩资源在线| 91精品中文在线| 噜噜噜躁狠狠躁狠狠精品视频| 一二三不卡视频| 欧美精品一二三| 8x8ⅹ拨牐拨牐拨牐在线观看| 成人蜜桃视频| 日韩av在线播放中文字幕| 欧美激情精品久久| 国产午夜精品全部视频播放| 爱高潮www亚洲精品| 精品少妇无遮挡毛片| 亚洲国产你懂的| 超碰最新在线| 日本一区二区三区视频在线播放| 日韩经典一区二区|