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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

ConcurrentHashMap 源码

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

?1.7 構造函數

// 16 0.75 16public ConcurrentHashMap(int initialCapacity,float loadFactor, int concurrencyLevel) {if (!(loadFactor > 0) || initialCapacity < 0 || concurrencyLevel <= 0)throw new IllegalArgumentException();if (concurrencyLevel > MAX_SEGMENTS) //1 << 16 65536concurrencyLevel = MAX_SEGMENTS;// Find power-of-two sizes best matching arguments//找到最接近的2的冪次方數int sshift = 0;int ssize = 1;//segment數組的長度while (ssize < concurrencyLevel) {++sshift; // 1 2 3 [4] 5 取hash的高四位,put時候用高4(sshift)位求segment數組的index值,低4位用于求hashtable[]的index值ssize <<= 1;//左移 2 4 8 [16] 32}this.segmentShift = 32 - sshift; //28this.segmentMask = ssize - 1;// 16 -1(0000 1111) 用來取table index = hash & (ssize -1)if (initialCapacity > MAXIMUM_CAPACITY)//1 << 30 1073741824initialCapacity = MAXIMUM_CAPACITY;int c = initialCapacity / ssize; // 16/16 = 1 每個segment里面的hashEntry數組的數量if (c * ssize < initialCapacity) //initialCapacity=16 初始參數 保證總hashEntry數量大于初始化得數量++c;int cap = MIN_SEGMENT_TABLE_CAPACITY; // MIN_SEGMENT_TABLE_CAPACITY = 2while (cap < c)cap <<= 1;//左移 2的冪次數 hashEntry[]數組的長度也要是2的冪次方// create segments and segments[0]Segment<K,V> s0 =new Segment<K,V>(loadFactor, (int)(cap * loadFactor),(HashEntry<K,V>[])new HashEntry[cap]);Segment<K,V>[] ss = (Segment<K,V>[])new Segment[ssize];UNSAFE.putOrderedObject(ss, SBASE, s0); // ordered write of segments[0]//Unsafe CAS技術this.segments = ss;}

1.7 ConcurrentHashmap.put()

@SuppressWarnings("unchecked")public V put(K key, V value) {Segment<K,V> s;if (value == null)throw new NullPointerException();int hash = hash(key);//segmentShift默認值是32 -4 =28,int值一共32位 所以取hash值的高四位int j = (hash >>> segmentShift) & segmentMask;//使用hash值的高4位 &segmentMask是segment長度減1if ((s = (Segment<K,V>)UNSAFE.getObject // Unsafe檢查segment時候存在(segments, (j << SSHIFT) + SBASE)) == null) // in ensureSegments = ensureSegment(j); //新建并使用CAS插入segmentreturn s.put(key, hash, value, false);//將鍵值對插入Segment}

Segment.put()

Segment.putfinal V put(K key, int hash, V value, boolean onlyIfAbsent) {HashEntry<K,V> node = tryLock() ? null :scanAndLockForPut(key, hash, value);V oldValue;try {HashEntry<K,V>[] tab = table;int index = (tab.length - 1) & hash;HashEntry<K,V> first = entryAt(tab, index);//獲取第一個節點for (HashEntry<K,V> e = first;;) {//遍歷鏈表if (e != null) {K k;if ((k = e.key) == key ||(e.hash == hash && key.equals(k))) {//找到key相等的HashEntry 并替換value值oldValue = e.value;if (!onlyIfAbsent) {e.value = value;++modCount;}break;}e = e.next;}//到達最后一個節點else {if (node != null)node.setNext(first);elsenode = new HashEntry<K,V>(hash, key, value, first);//創建新節點int c = count + 1;if (c > threshold && tab.length < MAXIMUM_CAPACITY)rehash(node);//擴容這個Segment的hashEntry[]數組elsesetEntryAt(tab, index, node);++modCount;count = c;oldValue = null;break;}}} finally {unlock();}return oldValue;}

?

總結

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

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