之前寫過這個 http://www.javashuo.com/article/p-hepcauak-ht.htmljava
今天看CyclicBarrier源碼,核心代碼 這一串oop
/** * Main barrier code, covering the various policies. */ private int dowait(boolean timed, long nanos) throws InterruptedException, BrokenBarrierException, TimeoutException { final ReentrantLock lock = this.lock; lock.lock();//獲取鎖 try { final Generation g = generation; if (g.broken) throw new BrokenBarrierException(); if (Thread.interrupted()) { breakBarrier(); throw new InterruptedException(); } int index = --count;//到達的線程數目 conut-- if (index == 0) { // tripped 到達數目時 boolean ranAction = false; try { final Runnable command = barrierCommand; if (command != null) command.run();//執行回調線程 ranAction = true; nextGeneration();//觸發激活全部線程 return 0; } finally { if (!ranAction) breakBarrier(); } } // loop until tripped, broken, interrupted, or timed out for (;;) { try { if (!timed) trip.await();//等待lock上的條件 定義:private final Condition trip = lock.newCondition(); else if (nanos > 0L) nanos = trip.awaitNanos(nanos); } catch (InterruptedException ie) { if (g == generation && ! g.broken) { breakBarrier(); throw ie; } else { // We're about to finish waiting even if we had not // been interrupted, so this interrupt is deemed to // "belong" to subsequent execution. Thread.currentThread().interrupt(); } } if (g.broken) throw new BrokenBarrierException(); if (g != generation) return index; if (timed && nanos <= 0L) { breakBarrier(); throw new TimeoutException(); } } } finally { lock.unlock(); } }
一直疑惑,當一個線程獲取lock.lock()鎖時,何時釋放的,要否則其餘線程進來時,根本進入不了方法,怎麼讓int index = --count;,進而觸發激活線程呢。糊塗好久,最後網上看到trip.await();解釋爲,等待lock上的條件(newCondition()),同時釋放lock鎖。這樣其餘線程才能得到鎖,再進入dowait方法。其實,若是不用鎖上的條件 (newCondition()) ,也就很差體會重入。this