閉鎖
延遲線程的進度直到到達終止狀態。相當於一扇門,在閉鎖到達結束狀態之前,這扇門一直是關閉着的。並沒有任何線程能夠通過。當到達結束狀態時,這扇門會打開允許所有的線程通過。閉鎖可以用來確保某些活動直到其他活動都完成後才繼續執行。閉鎖只可以使用一次。
1. 確保某個操作在其所需要的所有資源都被初始化後才能繼續執行,二元閉鎖可以用來表示”資源R已經被初始化”。
2. 確保某個服務在其所依賴的其他服務都已經啓動之後才啓動,每個服務都有一個相關的二元閉鎖。啓動服務S時,S在依賴的所有其他服務的閉鎖上等待。
3. 等待直到某個操作的所有參與者都就緒再繼續執行。這種情況中,閉鎖將達到結束狀態。
CountDownLatch是一種靈活的閉鎖實現,可以用於上述的各種情況中,可以使一個或多個線程等待一組事件發生。
countDown方法遞減計數器,await方法等待計數器達到零,或者等待中的線程中斷,或者超時。
案例:如果我們需要在所有線程創建完畢後纔開始線程的運行,可以在主線程中設置一個爲二元閉鎖,線程創建後,在這個閉鎖等待,等待所有創建完成後,進行一個countdown,所以所有創建好的線程可以在這時開始運行。
import java.util.concurrent.CountDownLatch;
public class ColletcionsPackageTest {
public long timeTasks(int nThreads, final Runnable task) throws InterruptedException {
final CountDownLatch startGate = new CountDownLatch(1);
final CountDownLatch endGate = new CountDownLatch(nThreads);
for (int i = 0; i < nThreads; i++) {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
startGate.await();
try {
task.run();
} finally{
// TODO: handle exception
endGate.countDown();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
long start=System.currentTimeMillis();
startGate.countDown();
endGate.await();
long end=System.currentTimeMillis();
return end-start;
}
}