一CountDownLatch
- CountDownLatch是JDK 5+裏面閉鎖的一個實現。
- 能夠使一個或多個線程等待其他線程完成各自的工作後再執行
- 與CountDownLatch第一次交互是主線程等待其它的線程,主線程必須在啓動其它線程後立即調用await方法,這樣主線程的操作就會在這個方法上阻塞,直到其他線程完成各自的任務。
- 其他的N個線程必須引用閉鎖對象,因爲他們需要通知CountDownLatch對象,他們已經完成了各自的任務,這種機制就是通過countDown()方法來完成的。每調用一次這個方法,在構造函數中初始化的count值就減1,所以當N個線程都調用了這個方法count的值等於0,然後主線程就能通過await方法,恢復自己的任務。
閉鎖(Latch):
- 一種同步方法
- 可以延遲線程的進度直到線程到達某個終點狀態。
- 一個閉鎖相當於一扇大門,在大門打開之前所有線程都被阻斷,一旦大門打開所有線程都將通過。
- 閉鎖的狀態是一次性的,它確保在閉鎖打開之前所有特定的活動都需要在閉鎖打開之後才能完成。
二主要方法
- public CountDownLatch(int count); //指定計數的次數,只能被設置1次
- public void countDown(); //調用此方法則計數減1
- public void await() throws InterruptedException //調用此方法會一直阻塞當前線程,直到計時器的值爲0,除非線程被中斷。
- Public Long getCount(); //得到當前的計數
- Public boolean await(long timeout, TimeUnit unit) //調用此方法會一直阻塞當前線程,直到計時器的值爲0,除非線程被中斷或者計數器超時,返回false代表計數器超時。
- From Object Inherited:Clone、equals、hashCode、notify、notifyALL、wait等。
三案例
public class CountdownLatchTest {
public static void main(String[] args) {
ExecutorService service = Executors.newCachedThreadPool();
final CountDownLatch cdOrder = new CountDownLatch(1);
final CountDownLatch cdAnswer = new CountDownLatch(3);
for(int i=0;i<3;i++){
Runnable runnable = new Runnable(){
public void run(){
try {
System.out.println("子線程"+Thread.currentThread().getName() +"正準備接受命令");
//調用此方法會一直阻塞當前線程,直到計時器的值爲0,除非線程被中斷。
cdOrder.await();
System.out.println("子線程"+Thread.currentThread().getName() +"已接受命令");
Thread.sleep((long)(Math.random()*5000));
System.out.println("子線程"+Thread.currentThread().getName() +"迴應命令處理結果");
//調用此方法則計數減1
cdAnswer.countDown();
} catch (Exception e) {
e.printStackTrace();
}
}
};
service.execute(runnable);
}
try {
Thread.sleep((long)(Math.random()*5000));
System.out.println("主線程"+Thread.currentThread().getName() +"即將發佈命令");
//調用此方法則計數減1,調用該方法執行,上面的線程會等待命令
cdOrder.countDown();
System.out.println("主線程"+Thread.currentThread().getName() +"已發送命令,正在等待結果");
//主線程等待,直到子線程都回應才走
cdAnswer.await();
System.out.println("主線程"+Thread.currentThread().getName() +"已收到所有響應結果");
} catch (Exception e) {
e.printStackTrace();
}
service.shutdown();
}
}
4結果
子線程pool-1-thread-1正準備接受命令
子線程pool-1-thread-2正準備接受命令
子線程pool-1-thread-3正準備接受命令
主線程main即將發佈命令
主線程main已發送命令,正在等待結果
子線程pool-1-thread-1已接受命令
子線程pool-1-thread-2已接受命令
子線程pool-1-thread-3已接受命令
子線程pool-1-thread-3迴應命令處理結果
子線程pool-1-thread-1迴應命令處理結果
子線程pool-1-thread-2迴應命令處理結果
主線程main已收到所有響應結果