ConcurrentHashMap的源码分析-扩容结束以后的退出机制
生活随笔
收集整理的這篇文章主要介紹了
ConcurrentHashMap的源码分析-扩容结束以后的退出机制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
如果線程擴容結束,那么需要退出,就會執行transfer方法的如下代碼
//i<0說明已經遍歷完舊的數組,也就是當前線程已經處理完所有負責的bucket if (i < 0 || i >= n || i + n >= nextn) { int sc; if (finishing) {//如果完成了擴容 nextTable = null;//刪除成員變量 table = nextTab;//更新table數組 sizeCtl = (n << 1) - (n >>> 1);//更新閾值(32*0.75=24) return; }// sizeCtl 在遷移前會設置為 (rs << RESIZE_STAMP_SHIFT) + 2 // 然后,每增加一個線程參與遷移就會將 sizeCtl 加 1, // 這里使用 CAS 操作對 sizeCtl 的低16位進行減 1,代表做完了屬于自己的任務 if (U.compareAndSwapInt(this, SIZECTL, sc = sizeCtl, sc - 1)) { 第一個擴容的線程,執行transfer方法之前,會設置 sizeCtl = (resizeStamp(n) << RESIZE_STAMP_SHIFT) + 2) 后續幫其擴容的線程,執行transfer方法之前,會設置 sizeCtl = sizeCtl+1 每一個退出transfer的方法的線程,退出之前,會設置 sizeCtl = sizeCtl-1 那么最后一個線程退出時:必然有 sc == (resizeStamp(n) << RESIZE_STAMP_SHIFT) + 2),即 (sc - 2) == resizeStamp(n) << RESIZE_STAMP_SHIFT // 如果 sc - 2 不等于標識符左移 16 位。如果他們相等了,說明沒有線程在幫助他們擴容了。也就是說,擴容結束了。 if ((sc - 2) != resizeStamp(n) << RESIZE_STAMP_SHIFT) return; // 如果相等,擴容結束了,更新 finising 變量 finishing = advance = true; // 再次循環檢查一下整張表 i = n; // recheck before commit } }?
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的ConcurrentHashMap的源码分析-扩容结束以后的退出机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ConcurrentHashMap的源码
- 下一篇: ConcurrentHashMap的源码