日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CopyOnWriteArrayList源码解析

發布時間:2024/4/17 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CopyOnWriteArrayList源码解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

此文已由作者趙計剛授權網易云社區發布。

歡迎訪問網易云社區,了解更多網易技術產品運營經驗。


注:在看這篇文章之前,如果對HashMap的層不清楚的話,建議先去看看HashMap源碼解析。

http://www.cnblogs.com/java-zhao/p/5106189.html

1、對于ConcurrentHashMap需要掌握以下幾點

  • Map的創建:ConcurrentHashMap()

  • 往Map中添加鍵值對:即put(Object key, Object value)方法

  • 獲取Map中的單個對象:即get(Object key)方法

  • 刪除Map中的對象:即remove(Object key)方法

  • 判斷對象是否存在于Map中:containsKey(Object key)

  • 遍歷Map中的對象:即keySet().iterator(),在實際中更常用的是增強型的for循環去做遍歷

2、ConcurrentHashMap的創建

注:在往下看之前,心里先有這樣一個映像:ConcurrentHashMap的數據結構:一個指定個數的Segment數組,數組中的每一個元素Segment相當于一個HashTable

2.1、使用方法:

Map<String,?Object>?map?=?new?ConcurrentHashMap<String,?Object>();

2.2、源代碼:

?ConcurrentHashMap相關屬性:

????/***?用于分段*///?根據這個數來計算segment的個數,segment的個數是僅小于這個數且是2的幾次方的一個數(ssize)static?final?int?DEFAULT_CONCURRENCY_LEVEL?=?16;//?最大的分段(segment)數(2的16次方)static?final?int?MAX_SEGMENTS?=?1?<<?16;/***?用于HashEntry*///?默認的用于計算Segment數組中的每一個segment的HashEntry[]的容量,但是并不是每一個segment的HashEntry[]的容量static?final?int?DEFAULT_INITIAL_CAPACITY?=?16;//?默認的加載因子(用于resize)static?final?float?DEFAULT_LOAD_FACTOR?=?0.75f;//?用于計算Segment數組中的每一個segment的HashEntry[]的最大容量(2的30次方)static?final?int?MAXIMUM_CAPACITY?=?1?<<?30;/***?segments數組*?每一個segment元素都看做是一個HashTable*/final?Segment<K,?V>[]?segments;/***?用于擴容*/final?int?segmentMask;//?用于根據給定的key的hash值定位到一個Segmentfinal?int?segmentShift;//?用于根據給定的key的hash值定位到一個Segment

Segment類(ConcurrentHashMap的內部類)

????/***?一個特殊的HashTable*/static?final?class?Segment<K,?V>?extends?ReentrantLock?implementsSerializable?{private?static?final?long?serialVersionUID?=?2249069246763182397L;transient?volatile?int?count;//?該Segment中的包含的所有HashEntry中的key-value的個數transient?int?modCount;//?并發標記/**?元素個數超出了這個值就擴容?threshold==(int)(capacity?*?loadFactor)*?值得注意的是,只是當前的Segment擴容,所以這是Segment自己的一個變量,而不是ConcurrentHashMap的*/transient?int?threshold;transient?volatile?HashEntry<K,?V>[]?table;//?鏈表數組final?float?loadFactor;/***?這里要注意一個很不好的編程習慣,就是小寫l,容易與數字1混淆,所以最好不要用小寫l,可以改為大寫L*/Segment(int?initialCapacity,?float?lf)?{loadFactor?=?lf;//每個Segment的加載因子setTable(HashEntry.<K,?V>?newArray(initialCapacity));}/***?創建一個Segment數組,容量為i*/@SuppressWarnings("unchecked")static?final?<K,?V>?Segment<K,?V>[]?newArray(int?i)?{return?new?Segment[i];}/***?Sets?table?to?new?HashEntry?array.?Call?only?while?holding?lock?or?in*?constructor.*/void?setTable(HashEntry<K,?V>[]?newTable)?{threshold?=?(int)?(newTable.length?*?loadFactor);//?設置擴容值table?=?newTable;//?設置鏈表數組}

說明:只列出了Segement的全部屬性和創建ConcurrentHashMap時所用到的方法。

HashEntry類(ConcurrentHashMap的內部類)

????/***?Segment中的HashEntry節點?類比HashMap中的Entry節點*/static?final?class?HashEntry<K,?V>?{final?K?key;//?鍵final?int?hash;//hash值volatile?V?value;//?實現線程可見性final?HashEntry<K,?V>?next;//?下一個HashEntryHashEntry(K?key,?int?hash,?HashEntry<K,?V>?next,?V?value)?{this.key?=?key;this.hash?=?hash;this.next?=?next;this.value?=?value;}/**?創建HashEntry數組,容量為傳入的i*/@SuppressWarnings("unchecked")static?final?<K,?V>?HashEntry<K,?V>[]?newArray(int?i)?{return?new?HashEntry[i];}}

ConcurrentHashMap(int initialCapacity,float loadFactor,int concurrencyLevel)

?1?????/**2??????*?創建ConcurrentHashMap3??????*?@param?initialCapacity?用于計算Segment數組中的每一個segment的HashEntry[]的容量,?但是并不是每一個segment的HashEntry[]的容量4??????*?@param?loadFactor5??????*?@param?concurrencyLevel?用于計算Segment數組的大小(可以傳入不是2的幾次方的數,但是根據下邊的計算,最終segment數組的大小ssize將是2的幾次方的數)6??????*?7??????*?步驟:8??????*?這里以默認的無參構造器參數為例,initialCapacity==16,loadFactor==0.75f,concurrencyLevel==169??????*?1)檢查各參數是否符合要求 10??????*?2)根據concurrencyLevel(16),計算Segment[]的容量ssize(16)與擴容移位條件sshift(4) 11??????*?3)根據sshift與ssize計算將來用于定位到相應Segment的參數segmentShift與segmentMask 12??????*?4)根據ssize創建Segment[]數組,容量為ssize(16) 13??????*?5)根據initialCapacity(16)與ssize計算用于計算HashEntry[]容量的參數c(1) 14??????*?6)根據c計算HashEntry[]的容量cap(1) 15??????*?7)根據cap與loadFactor(0.75)為每一個Segment[i]都實例化一個Segment 16??????*?8)每一個Segment的實例化都做下面這些事兒: 17??????*?8.1)為當前的Segment初始化其loadFactor為傳入的loadFactor(0.75) 18??????*?8.2)創建一個HashEntry[],容量為傳入的cap(1) 19??????*?8.3)根據創建出來的HashEntry的容量(1)和初始化的loadFactor(0.75),計算擴容因子threshold(0) 20??????*?8.4)初始化Segment的table為剛剛創建出來的HashEntry 21??????*/ 22?????public?ConcurrentHashMap(int?initialCapacity,float?loadFactor,int?concurrencyLevel)?{ 23?????????//?檢查參數情況 24?????????if?(loadFactor?<=?0f?||?initialCapacity?<?0?||?concurrencyLevel?<=?0) 25?????????????throw?new?IllegalArgumentException(); 26? 27?????????if?(concurrencyLevel?>?MAX_SEGMENTS) 28?????????????concurrencyLevel?=?MAX_SEGMENTS; 29? 30?????????/** 31??????????*?找一個能夠正好小于concurrencyLevel的數(這個數必須是2的幾次方的數) 32??????????*?eg.concurrencyLevel==16==>sshift==4,ssize==16 33??????????*?當然,如果concurrencyLevel==15也是上邊這個結果 34??????????*/ 35?????????int?sshift?=?0; 36?????????int?ssize?=?1;//?segment數組的長度 37?????????while?(ssize?<?concurrencyLevel)?{ 38?????????????++sshift; 39?????????????ssize?<<=?1;//?ssize=ssize*2 40?????????} 41? 42?????????segmentShift?=?32?-?sshift;//?eg.segmentShift==32-4=28?用于根據給定的key的hash值定位到一個Segment 43?????????segmentMask?=?ssize?-?1;//?eg.segmentMask==16-1==15?用于根據給定的key的hash值定位到一個Segment 44?????????this.segments?=?Segment.newArray(ssize);//?構造出了Segment[ssize]數組?eg.Segment[16] 45? 46?????????/* 47??????????*?下面將為segment數組中添加Segment元素 48??????????*/ 49?????????if?(initialCapacity?>?MAXIMUM_CAPACITY) 50?????????????initialCapacity?=?MAXIMUM_CAPACITY; 51?????????int?c?=?initialCapacity?/?ssize;//?eg.initialCapacity==16,c==16/16==1 52?????????if?(c?*?ssize?<?initialCapacity)//?eg.initialCapacity==17,c==17/16=1,這時1*16<17,所以c=c+1==2 53?????????????++c;//?為了少執行這一句,最好將initialCapacity設置為2的幾次方 54?????????int?cap?=?1;//?每一個Segment中的HashEntry[]的初始化容量 55?????????while?(cap?<?c) 56?????????????cap?<<=?1;//?創建容量 57? 58?????????for?(int?i?=?0;?i?<?this.segments.length;?++i) 59?????????????//?這一塊this.segments.length就是ssize,為了不去計算這個值,可以直接改成i<ssize 60?????????????this.segments[i]?=?new?Segment<K,?V>(cap,?loadFactor); 61?????}

注意:這個方法里邊我在頭部所寫的注釋非常重要,在這塊注釋寫明了:

  • 每一個參數的作用

  • 整個ConcurrentHashMap的一個創建步驟(以默認的參數值為例)


免費領取驗證碼、內容安全、短信發送、直播點播體驗包及云服務器等套餐

更多網易技術、產品、運營經驗分享請點擊。


相關文章:
【推薦】?十年?杭研技術秀 | “網易云存儲服務”從0到1發展之路
【推薦】?當我們在談論multidex65535時,我們在談論什么

轉載于:https://www.cnblogs.com/zyfd/p/10150816.html

總結

以上是生活随笔為你收集整理的CopyOnWriteArrayList源码解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 免费久久一级欧美特大黄 | 伊人成人在线视频 | 日韩av中文字幕在线免费观看 | 波多野结衣1区 | 国产在线第一页 | 蜜臀久久99精品久久一区二区 | 激情成人综合 | 中文字幕av专区 | 玩弄丰满少妇xxxxx性多毛 | 婷婷的五月天 | 九色精品视频 | 精品国产一区二区三区无码 | 少妇粉嫩小泬喷水视频www | 国产乱人乱偷精品视频 | 国产视频在线免费观看 | 国内自拍一区 | 国产精品一区一区三区 | 日本真人做爰免费视频120秒 | 成人在线不卡视频 | 国产又粗又猛视频免费 | 村姑电影在线播放免费观看 | 久久嗨| 伊是香蕉大人久久 | 日韩在线一区二区三区四区 | 欧美日韩a | 亚洲三级视频在线观看 | 欧美性猛交99久久久久99按摩 | 性自由色xxxx免费视频 | 性视频在线 | 中国美女一级片 | 午夜视频在线观看一区二区 | 国产99久久久国产精品成人免费 | 亚洲成a人在线观看 | 免费一级全黄少妇性色生活片 | 亚洲日本中文 | 日韩美女啪啪 | 久久人| 天天操天天爱天天干 | 日韩和的一区二区 | 国产a视频精品免费观看 | 熟女人妻在线视频 | 日韩久久精品视频 | 尤物视频在线免费观看 | 91免费视频网址 | 天天5g天天看 | 兄弟兄弟全集免费观看 | 俺来也在线视频 | 亚洲一区二区三区麻豆 | 蜜桃av在线免费观看 | 成人免费网视频 | 亚洲国产精品国自产拍av | 亚洲国产精品成人无码区 | 91成人免费版 | 国产精品国产精品国产专区 | 日日夜夜中文字幕 | 精品777| 成人三级在线播放 | 中文字幕黑丝 | 日日射日日干 | www.成人国产 | 精品一区二区三区免费毛片 | 日韩久久久 | 国产精品美女久久久久久久 | 中文字幕69页 | 亚洲人做受 | 欧美日色 | 九九综合 | 四虎影视成人永久免费观看亚洲欧美 | 久久视频免费看 | 午夜影院在线观看免费 | 男女啪啪在线观看 | 青青青青在线 | 一区二区在线 | www.麻豆av.com | 一级免费片 | 麻豆国产视频 | 国产在线一级片 | 草草影院ccyycom | 日韩成人精品在线 | 国产精品无码久久久久久 | 九九午夜视频 | 麻豆精品国产传媒 | 蜜桃无码一区二区三区 | 欧美另类视频在线 | 欧美日韩国产一区二区三区在线观看 | 欧美一级做a爰片久久高潮 久热国产精品视频 | 在线观看亚洲一区二区 | 老司机午夜免费福利 | 精品久久久久久久久久久久久久久久 | 男人和女人搞鸡 | 亚洲精华国产精华精华液网站 | 欧美欧美欧美欧美 | 欧美综合网站 | 很黄很黄的网站 | 欧美午夜视频在线观看 | 国产乱子伦精品视频 | 最近最新中文字幕 | 啪视频在线 | 伊人365 |