CountDownLatch允許一個或多個線程等待其他線程完成操作。 假如有這樣一個需求:我們需要解析一個Excel里多個sheet的數據,此時可以考慮使用多線程,每個線程解析一個sheet里的數據,等到所有的sheet都解析完之後,程式需要提示解析完成。在這個需求中,要實現主線程等待所有線程完成s ...
CountDownLatch允許一個或多個線程等待其他線程完成操作。
假如有這樣一個需求:我們需要解析一個Excel里多個sheet的數據,此時可以考慮使用多線程,每個線程解析一個sheet里的數據,等到所有的sheet都解析完之後,程式需要提示解析完成。在這個需求中,要實現主線程等待所有線程完成sheet的解析操作,最簡單的做法是使用join()方法。
public class JoinCountDownLatchTest {
public static void main(String[] args) throws InterruptedException {
Thread parser1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("parser1 finish");
}
});
Thread parser2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("parser2 finish");
}
});
parser1.start();
parser2.start();
parser1.join();
parser2.join();
System.out.println("all parser finish");
}
}
result:
parser1 finish
parser2 finish
all parser finish
主線程會等待線程1和2運行完成後再運行。
在JDK 1.5之後的併發包中提供的CountDownLatch也可以實現join的功能,並且比join的功能更多
CountDownLatch的構造函數接收一個int類型的參數作為計數器,如果你想等待N個點完成,這裡就傳入N。
當我們調用CountDownLatch的countDown方法時,N就會減1,CountDownLatch的await方法
會阻塞當前線程,直到N變成零。由於countDown方法可以用在任何地方,所以這裡說的N個點,可以是N個線程,也可以是1個線程里的N個執行步驟。用在多個線程時,只需要把這個CountDownLatch的引用傳遞到線程里即可。如果有某個線程處理得比較慢,我們不可能讓主線程一直等待,所以可以使用另外一個帶指定時間的await方法——await(long time,TimeUnit unit),這個方法等待特定時間後,就會不再阻塞當前線程。join也有類似的方法。
public class Test {
static CountDownLatch c = new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
System.out.println("線程1運行任務1");
c.countDown();
System.out.println("線程1運行任務2");
c.countDown();
}).start();
c.await();
System.out.println("主線程匯聚任務");
}
}
result:
線程1運行任務1
線程1運行任務2
主線程匯聚任務
註意的是:計數器必須大於等於0,只是等於0時候,計數器就是零,調用await方法時不會
阻塞當前線程。CountDownLatch不可能重新初始化或者修改CountDownLatch對象的內部計數
器的值。