閉鎖,一個大門,滿足一定的條件後開門(8點了開學校大門)。
/**
* 閉鎖
*/
public class TestHarness {//創建一些線程,併發的執行給定的任務
//每一個工作線程要做的第一件事是等待開始門閥打開,這樣做能確保
//所有線程都做好準備時,纔開始工作。
//每個線程的最後一個工作是結束門閥減1,這樣做使控制線程有效的等待,
// 直到最後一個工作線程完成,結束後返回用時(納秒)
//Q:爲什麼不在線程創建的時候就立即運行
//A:簡單的創建就啓動線程,那麼先啓動的就比後啓動的具有“領先優勢”,並且
//根據活動線程數的增加或者減少,這樣的競爭度也在不斷改變。
//開始門閥讓控制線程能夠同事釋放所有工作線程,
//結束門閥讓控制線程能夠等待最後一個線程完成任務,而不是順序等待每一個線程結束
public long timeTasks(int nThreads, final Runnable task) throws InterruptedException {
//開始閥門,初始化爲1,
final CountDownLatch startGate = new CountDownLatch(1);
//結束閥門,初始化爲工作線程的數量
final CountDownLatch endGate = new CountDownLatch(nThreads);
for (int i = 0; i < nThreads; i++) {//
Thread thread = new Thread(() -> {
try {
startGate.await();//等待計數器到達0,此時所有需要等待的事件都已發生。
// 如果計數器入口時值爲非零,await會一直阻塞直到計數器爲零,或者等待線程中斷以及超時
try {
task.run();
} finally {
endGate.countDown();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.start();
}
long startTime = System.nanoTime();
startGate.countDown();
endGate.await();
long endTime = System.nanoTime();
return endTime - startTime;
}
}