中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

學(xué)校網(wǎng)站的英文奇葩網(wǎng)站100個

學(xué)校網(wǎng)站的英文,奇葩網(wǎng)站100個,做服裝外貿(mào)的網(wǎng)站建設(shè),硬件設(shè)計包括哪些內(nèi)容文章目錄 六、并發(fā)集合1 ConcurrentHashMap1.1 存儲結(jié)構(gòu)1.2 存儲操作1.2.1 put方法1.2.2 putVal方法-散列算法1.2.3 putVal方法-添加數(shù)據(jù)到數(shù)組&初始化數(shù)組1.2.4 putVal方法-添加數(shù)據(jù)到鏈表1.3 擴容操作1.3.1 treeifyBin方法觸發(fā)擴容1.3.2 tryPresize方法-針對putAll的初始…

文章目錄

  • 六、并發(fā)集合
    • 1 ConcurrentHashMap
      • 1.1 存儲結(jié)構(gòu)
      • 1.2 存儲操作
        • 1.2.1 put方法
        • 1.2.2 putVal方法-散列算法
        • 1.2.3 putVal方法-添加數(shù)據(jù)到數(shù)組&初始化數(shù)組
        • 1.2.4 putVal方法-添加數(shù)據(jù)到鏈表
      • 1.3 擴容操作
        • 1.3.1 treeifyBin方法觸發(fā)擴容
        • 1.3.2 tryPresize方法-針對putAll的初始化操作
        • 1.3.3 tryPreSize方法-計算擴容戳&查看BUG
        • 1.3.4 tryPreSize方法-對sizeCtl的修改&條件判斷的BUG
        • 1.3.5 transfer方法-計算每個線程遷移的長度
        • 1.3.6 transfer方法-構(gòu)建新數(shù)組&查看標識屬性
        • 1.3.7 transfer方法-線程領(lǐng)取遷移任務(wù)
        • 1.3.8 transfer方法-遷移結(jié)束操作
        • 1.3.9 transfer方法-遷移數(shù)據(jù)(鏈表)
        • 1.3.10 helpThransfer方法-協(xié)助擴容
      • 1.4 紅黑樹操作
        • 1.4.1 什么是紅黑樹
        • 1.4.2 treeifyBin方法-封裝TreeNode和雙向鏈表
        • 1.4.3 TreeBin有參構(gòu)造-雙向鏈表轉(zhuǎn)為紅黑樹
        • 1.4.4 balanceInsertion方法-保證紅黑樹平衡以及特性
        • 1.4.5 putTreeVal方法-添加節(jié)點
        • 1.4.6 TreeBin的鎖操作
        • 1.4.7 transfer遷移數(shù)據(jù)
      • 1.5 查詢數(shù)據(jù)
        • 1.5.1 get方法-查詢數(shù)據(jù)的入口
        • 1.5.2 ForwardingNode的find方法
        • 1.5.3 ReservationNode的find方法
        • 1.5.4 TreeBin的find方法
        • 1.5.5 TreeNode的findTreeNode方法
      • 1.6 ConcurrentHashMap其它方法
        • 1.6.1 compute方法
        • 1.6.2 compute方法源碼分析
        • 1.6.3 computeIfPresent、computeIfAbsent、compute的區(qū)別
        • 1.6.4 replace方法詳解
        • 1.6.5 merge方法詳解
      • 1.7 ConcurrentHashMap計數(shù)器
        • 1.7.1 addCount方法分析
        • 1.7.2 size方法分析
      • 1.8 JDK1.7的HashMap的環(huán)形鏈表問題
    • 2 CopyOnWriteArrayList
      • 2.1 CopyOnWriteArrayList介紹
      • 2.2 核心屬性&方法
      • 2.3 讀操作
      • 2.4 寫操作
      • 2.5 移除數(shù)據(jù)
      • 2.6 覆蓋數(shù)據(jù)&清空集合
      • 2.7 迭代器

六、并發(fā)集合

1 ConcurrentHashMap

1.1 存儲結(jié)構(gòu)

ConcurrentHashMap 是線程安全的 HashMap,在 JDK1.8 中是以 CAS + synchronized 實現(xiàn)的線程安全。

  • CAS:在沒有 hash 沖突時(Node 要放在數(shù)組上時)
  • synchronized:在出現(xiàn) hash 沖突時(Node 存放的位置已經(jīng)有數(shù)據(jù)了)
  • 存儲結(jié)構(gòu):數(shù)組+鏈表+紅黑樹

image.png

1.2 存儲操作

1.2.1 put方法

public V put(K key, V value) {// 在調(diào)用put方法時,會調(diào)用putVal方法,第三個參數(shù)默認傳遞false// 在調(diào)用putIfAbsent時,會調(diào)用putVal方法,第三個參數(shù)傳遞true// false: 代表key一致時,直接覆蓋數(shù)據(jù)// true: 代表key一致時,什么都不做,key不存在正常添加(類似Redis的setnx)return putVal(key, value, false);
}

1.2.2 putVal方法-散列算法

final V putVal(K key, V value, boolean onlyIfAbsent) {// ConcurrentHashMap不允許key或者value出現(xiàn)為null的值,跟HashMap的區(qū)別if (key == null || value == null) throw new NullPointerException();// 根據(jù)key的hashCode計算出一個hash值,后期得出當前key-value要存儲在哪個數(shù)組索引位置int hash = spread(key.hashCode());int binCount = 0; // 一個標識,在后面有用// ...省略大量代碼
}
// 計算當前Node的hash值的方法
static final int spread(int h) {// 將key的hashCode值的高低16位進行^運算,最終又與HASH_BITS進行了&運算// 將高位的hash也參與到計算索引位置的運算當中,盡可能將數(shù)據(jù)打散// 為什么HashMap、ConcurrentHashMap,都要求數(shù)組長度為2^n// HASH_BITS讓hash值的最高位符號位肯定為0,代表當前hash值默認情況下一定是正數(shù),因為hash值為負數(shù)時,有特殊的含義// static final int MOVED     = -1; // 代表當前hash位置的數(shù)據(jù)正在擴容// static final int TREEBIN   = -2; // 代表當前hash位置下掛載的是一個紅黑樹// static final int RESERVED  = -3; // 預(yù)留當前索引位置return (h ^ (h >>> 16)) & HASH_BITS;// 計算數(shù)組放到哪個索引位置的方法   (f = tabAt(tab, i = (n - 1) & hash)// n:是數(shù)組的長度
}
運算方式
00000000 00000000 00000000 00001111  - 15 (n - 1)
&
((00001101 00001101 00101111 10001111  - h^00000000 00000000 00001101 00001101  - h >>> 16)&01111111 11111111 11111111 11111111  - HASH_BITS
)

1.2.3 putVal方法-添加數(shù)據(jù)到數(shù)組&初始化數(shù)組

  • 添加數(shù)據(jù)到數(shù)組:CAS
  • 初始化數(shù)組:DCL + CAS
final V putVal(K key, V value, boolean onlyIfAbsent) {// 省略部分代碼...// 將Map的數(shù)組賦值給tab,死循環(huán)for (Node<K,V>[] tab = table;;) {// n: 數(shù)組長度;i: 當前Node需要存放的索引位置// f: 當前數(shù)組i索引位置的Node對象;fn: 當前數(shù)組i索引位置上數(shù)據(jù)的hash值Node<K,V> f; int n, i, fh;// 判斷當前數(shù)組是否還沒有初始化if (tab == null || (n = tab.length) == 0)tab = initTable();	// 將數(shù)組進行初始化// 基于 (n - 1) & hash 計算出當前Node需要存放在哪個索引位置// 基于tabAt獲取到i位置的數(shù)據(jù)else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {// 現(xiàn)在數(shù)組的i位置上沒有數(shù)據(jù),基于CAS的方式將數(shù)據(jù)存在i位置上if (casTabAt(tab, i, null, new Node<K,V>(hash, key, value, null)))break; // 如果成功,執(zhí)行break跳出循環(huán),插入數(shù)據(jù)成功}// 判斷當前位置數(shù)據(jù)是否正在擴容else if ((fh = f.hash) == MOVED)tab = helpTransfer(tab, f);	// 讓當前插入數(shù)據(jù)的線程協(xié)助擴容// 省略部分代碼...}addCount(1L, binCount);return null;
}
// 初始化數(shù)組方法
private final Node<K,V>[] initTable() {Node<K,V>[] tab; int sc;// 再次判斷數(shù)組沒有初始化,并且完成tab的賦值while ((tab = table) == null || tab.length == 0) {// sizeCtl:是數(shù)組在初始化和擴容操作時的一個控制變量。// -1: 代表當前數(shù)組正在初始化;// 小于-1: 低16位代表當前數(shù)組正在擴容的線程個數(shù)(如果1個線程擴容,值為-2,如果2個線程擴容,值為-3);// 0: 代表數(shù)組還沒初始化;// 大于0: 代表當前數(shù)組的擴容閾值,或者是當前數(shù)組的初始化大小// 將sizeCtl賦值給sc變量,并判斷是否小于0if ((sc = sizeCtl) < 0)Thread.yield(); // lost initialization race; just spin// 可以嘗試初始化數(shù)組,線程會以CAS的方式,將sizeCtl修改為-1,代表當前線程可以初始化數(shù)組else if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {try {	// 嘗試初始化// 再次判斷當前數(shù)組是否已經(jīng)初始化完畢if ((tab = table) == null || tab.length == 0) {// 開始初始化: 如果sizeCtl > 0,就初始化sizeCtl長度的數(shù)組;如果sizeCtl == 0,就初始化默認的長度16int n = (sc > 0) ? sc : DEFAULT_CAPACITY;// 初始化數(shù)組Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];// 將初始化的數(shù)組nt,賦值給tab和tabletable = tab = nt;// sc賦值為了數(shù)組長度 - 數(shù)組長度 右移 2位    16 - 4 = 12,將sc賦值為下次擴容的閾值sc = n - (n >>> 2);}} finally {// 將賦值好的sc,設(shè)置給sizeCtlsizeCtl = sc;}break;}}return tab;
}

1.2.4 putVal方法-添加數(shù)據(jù)到鏈表

  • 添加數(shù)據(jù)到鏈表:利用 synchronized 基于當前索引位置的Node,作為鎖對象
final V putVal(K key, V value, boolean onlyIfAbsent) {// 省略部分代碼...int binCount = 0;for (Node<K,V>[] tab = table;;) {// n: 數(shù)組長度;i: 當前Node需要存放的索引位置// f: 當前數(shù)組i索引位置的Node對象;fn: 當前數(shù)組i索引位置上數(shù)據(jù)的hash值Node<K,V> f; int n, i, fh;// 省略部分代碼...else {V oldVal = null;	// 聲明變量為oldValsynchronized (f) {	// 基于當前索引位置的Node,作為鎖對象// 判斷當前位置的數(shù)據(jù)還是之前的f么……(避免并發(fā)操作的安全問題)if (tabAt(tab, i) == f) {if (fh >= 0) {	// 再次判斷hash值是否大于0(不是樹)// binCount設(shè)置為1(在鏈表情況下,記錄鏈表長度的一個標識)binCount = 1;// 死循環(huán),每循環(huán)一次,對binCountfor (Node<K,V> e = f;; ++binCount) { K ek;// 當前i索引位置的數(shù)據(jù),是否和當前put的key的hash值一致if (e.hash == hash &&// 如果當前i索引位置數(shù)據(jù)的key和put的key == 返回為true// 或者equals相等((ek = e.key) == key || (ek != null && key.equals(ek)))) {// key一致,可能需要覆蓋數(shù)據(jù),當前i索引位置數(shù)據(jù)的value賦值給oldValoldVal = e.val;// 如果傳入的是false,代表key一致,覆蓋value;如果傳入的是true,代表key一致,什么都不做if (!onlyIfAbsent)e.val = value; // 覆蓋valuebreak;}Node<K,V> pred = e;	// 拿到當前指定的Node對象// 將e指向下一個Node對象,如果next指向的是一個null,可以掛在當前Node下面if ((e = e.next) == null) {// 將hash,key,value封裝為Node對象,掛在pred的next上pred.next = new Node<K,V>(hash, key, value, null);break;}}}// 省略部分代碼...}}if (binCount != 0) {if (binCount >= TREEIFY_THRESHOLD)	// binCount是否大于8(鏈表長度是否 >= 8)// 嘗試轉(zhuǎn)為紅黑樹或者擴容// 基于treeifyBin方法和上面的if判斷,可以得知鏈表想要轉(zhuǎn)為紅黑樹,必須保證數(shù)組長度大于等于64,并且鏈表長度大于等于8// 如果數(shù)組長度沒有達到64的話,會首先將數(shù)組擴容treeifyBin(tab, i);if (oldVal != null)	// 如果出現(xiàn)了數(shù)據(jù)覆蓋的情況,返回之前的值return oldVal;break;}}}// 省略部分代碼...
}

為什么鏈表長度為8轉(zhuǎn)換為紅黑樹,不是能其他數(shù)值嘛?

因為泊松分布

The main disadvantage of per-bin locks is that other update* operations on other nodes in a bin list protected by the same* lock can stall, for example when user equals() or mapping* functions take a long time.  However, statistically, under* random hash codes, this is not a common problem.  Ideally, the* frequency of nodes in bins follows a Poisson distribution* (http://en.wikipedia.org/wiki/Poisson_distribution) with a* parameter of about 0.5 on average, given the resizing threshold* of 0.75, although with a large variance because of resizing* granularity. Ignoring variance, the expected occurrences of* list size k are (exp(-0.5) * pow(0.5, k) / factorial(k)). The* first values are:** 0:    0.60653066* 1:    0.30326533* 2:    0.07581633* 3:    0.01263606* 4:    0.00157952* 5:    0.00015795* 6:    0.00001316* 7:    0.00000094* 8:    0.00000006* more: less than 1 in ten million

1.3 擴容操作

1.3.1 treeifyBin方法觸發(fā)擴容

// 在鏈表長度大于等于8時,嘗試將鏈表轉(zhuǎn)為紅黑樹
private final void treeifyBin(Node<K,V>[] tab, int index) {Node<K,V> b; int n, sc;// 數(shù)組不能為空if (tab != null) {// 數(shù)組的長度n,是否小于64if ((n = tab.length) < MIN_TREEIFY_CAPACITY)// 如果數(shù)組長度小于64,不能將鏈表轉(zhuǎn)為紅黑樹,先嘗試擴容操作tryPresize(n << 1);// 省略部分代碼……}
}

1.3.2 tryPresize方法-針對putAll的初始化操作

// size是將之前的數(shù)組長度 左移 1位得到的結(jié)果
private final void tryPresize(int size) {// 如果擴容的長度達到了最大值,就使用最大值,否則需要保證數(shù)組的長度為2的n次冪// 這塊的操作,是為了初始化操作準備的,因為調(diào)用putAll方法時,也會觸發(fā)tryPresize方法// 如果剛剛new的ConcurrentHashMap直接調(diào)用了putAll方法的話,會通過tryPresize方法進行初始化int c = (size >= (MAXIMUM_CAPACITY >>> 1)) ? MAXIMUM_CAPACITY :tableSizeFor(size + (size >>> 1) + 1);// 這些代碼和initTable一模一樣int sc;// 將sizeCtl的值賦值給sc,并判斷是否大于0,這里代表沒有初始化操作,也沒有擴容操作while ((sc = sizeCtl) >= 0) {// 將ConcurrentHashMap的table賦值給tab,并聲明數(shù)組長度nNode<K,V>[] tab = table; int n;// 數(shù)組是否需要初始化if (tab == null || (n = tab.length) == 0) {// 進來執(zhí)行初始化// sc是初始化長度,初始化長度如果比計算出來的c要大的話,直接使用sc,如果沒有sc大,說明sc無法容納下putAll中傳入的map,使用更大的數(shù)組長度n = (sc > c) ? sc : c;// 設(shè)置sizeCtl為-1,代表初始化操作if (U.compareAndSwapInt(this, SIZECTL, sc, -1)) {try {// 再次判斷數(shù)組的引用有沒有變化if (table == tab) {// 初始化數(shù)組Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n];// 數(shù)組賦值table = nt;// 計算擴容閾值sc = n - (n >>> 2);}} finally {// 最終賦值給sizeCtlsizeCtl = sc;}}}// 如果計算出來的長度c小于等于c,或者數(shù)組長度大于等于最大長度,直接退出循環(huán)結(jié)束方法else if (c <= sc || n >= MAXIMUM_CAPACITY)break;// 省略部分代碼...}
}// 將c這個長度設(shè)置到最近的2的n次冪的值,   15 -> 16     17 -> 32
// c == size + (size >>> 1) + 1
// size = 17
00000000 00000000 00000000 00010001
+ 
00000000 00000000 00000000 00001000
+
00000000 00000000 00000000 00000001
// c = 26
00000000 00000000 00000000 00011010
private static final int tableSizeFor(int c) { // c = 26// 00000000 00000000 00000000 00011001int n = c - 1;// 00000000 00000000 00000000 00011001// 00000000 00000000 00000000 00001100// 00000000 00000000 00000000 00011101n |= n >>> 1;// 00000000 00000000 00000000 00011101// 00000000 00000000 00000000 00000111// 00000000 00000000 00000000 00011111n |= n >>> 2;// 00000000 00000000 00000000 00011111// 00000000 00000000 00000000 00000001// 00000000 00000000 00000000 00011111n |= n >>> 4;// 00000000 00000000 00000000 00011111// 00000000 00000000 00000000 00000000// 00000000 00000000 00000000 00011111n |= n >>> 8;// 00000000 00000000 00000000 00011111n |= n >>> 16;// 00000000 00000000 00000000 00100000return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}

1.3.3 tryPreSize方法-計算擴容戳&查看BUG

private final void tryPresize(int size) {// n:數(shù)組長度while ((sc = sizeCtl) >= 0) {// 省略部分代碼…// 判斷當前的tab是否和table一致else if (tab == table) {// 計算擴容標識戳,根據(jù)當前數(shù)組的長度計算一個16位的擴容戳// 第一個作用是為了保證后面的sizeCtl賦值時,保證sizeCtl為小于-1的負數(shù)// 第二個作用用來記錄當前是從什么長度開始擴容的int rs = resizeStamp(n);// BUG --- sc < 0,永遠進不去if (sc < 0) { // 如果sc小于0,代表有線程正在擴容// 省略部分代碼……協(xié)助擴容的代碼(進不來~~~~)}// 代表沒有線程正在擴容,我是第一個擴容的。else if (U.compareAndSwapInt(this, SIZECTL, sc,(rs << RESIZE_STAMP_SHIFT) + 2))// 省略部分代碼……第一個擴容的線程……}}
}
// 計算擴容標識戳
// 32 =  00000000 00000000 00000000 00100000
// Integer.numberOfLeadingZeros(32) = 26
// 1 << (RESIZE_STAMP_BITS - 1) 
// 00000000 00000000 10000000 00000000
// 00000000 00000000 00000000 00011010
// 00000000 00000000 10000000 00011010
static final int resizeStamp(int n) {return Integer.numberOfLeadingZeros(n) | (1 << (RESIZE_STAMP_BITS - 1));
}

1.3.4 tryPreSize方法-對sizeCtl的修改&條件判斷的BUG

private final void tryPresize(int size) {// sc默認為sizeCtlwhile ((sc = sizeCtl) >= 0) {else if (tab == table) {// rs: 擴容戳  00000000 00000000 10000000 00011010int rs = resizeStamp(n);if (sc < 0) {// 說明有線程正在擴容,過來幫助擴容Node<K,V>[] nt;// 依然有BUG// 當前線程擴容時,老數(shù)組長度是否和我當前線程擴容時的老數(shù)組長度一致// 00000000 00000000 10000000 00011010if ((sc >>> RESIZE_STAMP_SHIFT) != rs  // 10000000 00011010 00000000 00000010 // 00000000 00000000 10000000 00011010// 這兩個判斷都是有問題的,核心問題就應(yīng)該先將rs左移16位,再追加當前值// 判斷當前擴容是否已經(jīng)即將結(jié)束|| sc == rs + 1   // sc == rs << 16 + 1 BUG// 判斷當前擴容的線程是否達到了最大限度|| sc == rs + MAX_RESIZERS   // sc == rs << 16 + MAX_RESIZERS BUG// 擴容已經(jīng)結(jié)束了|| (nt = nextTable) == null // 記錄遷移的索引位置,從高位往低位遷移,也代表擴容即將結(jié)束|| transferIndex <= 0)break;// 如果線程需要協(xié)助擴容,首先就是對sizeCtl進行+1操作,代表當前要進來一個線程協(xié)助擴容if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1))// 上面的判斷沒進去的話,nt就代表新數(shù)組transfer(tab, nt);}// 是第一個來擴容的線程// 基于CAS將sizeCtl修改為  10000000 00011010 00000000 00000010 // 將擴容戳左移16位之后,符號位是1,就代碼這個值為負數(shù),低16位在表示當前正在擴容的線程有多少個// 為什么低位值為2時,代表有一個線程正在擴容// 每一個線程擴容完畢后,會對低16位進行-1操作,當最后一個線程擴容完畢后,減1的結(jié)果還是-1,當值為-1時,要對老數(shù)組進行一波掃描,查看是否有遺漏的數(shù)據(jù)沒有遷移到新數(shù)組else if (U.compareAndSwapInt(this, SIZECTL, sc,(rs << RESIZE_STAMP_SHIFT) + 2))// 調(diào)用transfer方法,并且將第二個參數(shù)設(shè)置為null,就代表是第一次來擴容!transfer(tab, null);}}
}

1.3.5 transfer方法-計算每個線程遷移的長度

// 開始擴容   tab: oldTable
private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {// n: 數(shù)組長度// stride: 每個線程一次性遷移多少數(shù)據(jù)到新數(shù)組int n = tab.length, stride;// 基于CPU的內(nèi)核數(shù)量來計算,每個線程一次性遷移多少長度的數(shù)據(jù)最合理// NCPU = 4// 舉個栗子:數(shù)組長度為1024 - 512 - 256 - 128 / 4 = 32// MIN_TRANSFER_STRIDE = 16,為每個線程遷移數(shù)據(jù)的最小長度// 根據(jù)CPU計算每個線程一次遷移多長的數(shù)據(jù)到新數(shù)組,如果結(jié)果大于16,使用計算結(jié)果。 如果結(jié)果小于16,就使用最小長度16if ((stride = (NCPU > 1) ? (n >>> 3) / NCPU : n) < MIN_TRANSFER_STRIDE)stride = MIN_TRANSFER_STRIDE; // 省略部分代碼...
}

1.3.6 transfer方法-構(gòu)建新數(shù)組&查看標識屬性

// 以32長度數(shù)組擴容到64位例子
private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {// 省略部分代碼...// n: 老數(shù)組長度   32// stride: 步長   16// 第一個進來擴容的線程需要把新數(shù)組構(gòu)建出來if (nextTab == null) {try {// 將原數(shù)組長度左移一位,構(gòu)建新數(shù)組長度Node<K,V>[] nt = (Node<K,V>[])new Node<?,?>[n << 1];// 賦值操作nextTab = nt;} catch (Throwable ex) {   // 到這說明已經(jīng)達到數(shù)組長度的最大取值范圍sizeCtl = Integer.MAX_VALUE;// 設(shè)置sizeCtl后直接結(jié)束return;}// 對成員變量的新數(shù)組賦值nextTable = nextTab;// 遷移數(shù)據(jù)時,用到的標識,默認值為老數(shù)組長度transferIndex = n;   // 32}// 新數(shù)組長度int nextn = nextTab.length;  // 64// 在老數(shù)組遷移完數(shù)據(jù)后,做的標識ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab);// 遷移數(shù)據(jù)時,需要用到的標識boolean advance = true;boolean finishing = false; // 省略部分代碼...
}

1.3.7 transfer方法-線程領(lǐng)取遷移任務(wù)

// 以32長度擴容到64位為例子
private final void transfer(Node<K,V>[] tab, Node<K,V>[] nextTab) {// 省略部分代碼…// n: 32// stride: 16int n = tab.length, stride;if (nextTab == null) { // 省略部分代碼…nextTable = nextTab;	// 新數(shù)組// transferIndex:0transferIndex = n;}// nextn:64int nextn = nextTab.length;ForwardingNode<K,V> fwd = new ForwardingNode<K,V>(nextTab);// advance:true,代表當前線程需要接收任務(wù),然后再執(zhí)行遷移;如果為false,代表已經(jīng)接收完任務(wù)boolean advance = true;boolean finishing = false; // 是否遷移結(jié)束// i = 15     代表當前線程遷移數(shù)據(jù)的索引值for (int i = 0, bound = 0;;) {Node<K,V> f; int fh;	// f = null,fh = 0while (advance) {		// 當前線程要接收任務(wù)// nextIndex = 16,nextBound = 16int nextIndex, nextBound;// 對i進行--,并且判斷當前任務(wù)是否處理完畢!if (--i >= bound || finishing) // 第一次進來,這兩個判斷肯定進不去advance = false;// 判斷transferIndex是否小于等于0,代表沒有任務(wù)可領(lǐng)取,結(jié)束了// 在線程領(lǐng)取任務(wù)會,會對transferIndex進行修改,修改為transferIndex - stride// 在任務(wù)都領(lǐng)取完之后,transferIndex肯定是小于等于0的,代表沒有遷移數(shù)據(jù)的任務(wù)可以領(lǐng)取else if ((nextIndex = transferIndex) <= 0) {i = -1
http://www.risenshineclean.com/news/64430.html

相關(guān)文章:

  • 網(wǎng)站模板設(shè)計開發(fā)站長工具四葉草
  • wordpress怎么上傳logo百度關(guān)鍵詞優(yōu)化工具
  • 石家莊專業(yè)建站公司網(wǎng)頁版百度云
  • 代理服務(wù)器地址seo搜索引擎優(yōu)化服務(wù)
  • 騰訊云做網(wǎng)站需要報備百度人工服務(wù)熱線24小時
  • 專業(yè)網(wǎng)站設(shè)計哪家好可以做產(chǎn)品推廣的軟件有哪些
  • 代銷網(wǎng)站源碼seo優(yōu)化技術(shù)是什么
  • wordpress半透明主題關(guān)鍵詞優(yōu)化排名軟件
  • 禁止wordpress獲取隱私新手怎么入行seo
  • 武漢網(wǎng)站推廣霸屏寧波正規(guī)優(yōu)化seo軟件
  • 網(wǎng)站域名備案在哪里職業(yè)培訓(xùn)機構(gòu)需要什么資質(zhì)
  • 谷搜易外貿(mào)網(wǎng)站建設(shè)站長之家關(guān)鍵詞挖掘工具
  • 如何利用源代碼做網(wǎng)站今日頭條最新
  • 網(wǎng)站建設(shè)需求 百度文庫三十個知識點帶你學(xué)黨章
  • 盛澤做網(wǎng)站的微信賣貨小程序怎么做
  • 設(shè)計廣告圖用什么軟件好用有利于seo優(yōu)化的是
  • 網(wǎng)站的站內(nèi)結(jié)構(gòu)錨文本是如何做的seo指什么
  • 做電影網(wǎng)站模板教學(xué)設(shè)計免費注冊個人網(wǎng)站不花錢
  • java網(wǎng)站開發(fā)是干什么安徽網(wǎng)絡(luò)關(guān)鍵詞優(yōu)化
  • 工信局網(wǎng)站備案查詢溫州seo網(wǎng)站推廣
  • 中國企業(yè)網(wǎng)銀怎么轉(zhuǎn)賬seo推廣軟
  • 石家莊專業(yè)網(wǎng)站設(shè)計電話搜狗競價推廣效果怎么樣
  • 網(wǎng)站做下載功能網(wǎng)站代搭建維護
  • 滄州有沒有做網(wǎng)站的國外網(wǎng)站制作
  • 怎樣進行站點優(yōu)化seo高端培訓(xùn)
  • 什么做網(wǎng)站做個多少錢啊排名優(yōu)化seo
  • wordpress用windows會慢寧波seo關(guān)鍵詞優(yōu)化報價
  • 自己做的網(wǎng)站做登錄網(wǎng)店運營與推廣
  • 做競彩網(wǎng)站代理犯法么站長統(tǒng)計app軟件下載
  • 個人網(wǎng)站可以做企業(yè)宣傳個人如何做seo推廣