CountDownLatch使用
一、CountDownLatch介紹
1) CountDownLatch一個同步輔助類,在完成一組正在其他線程中執行的操作之前,它允許一個或多個線程一直等待
2) 有時候會有這樣的需求,多個線程同時工作,然後其中幾個可以隨意併發執行,但有一個線程需要等其他線程工作結束後,才能開始。
3) 舉個例子,開啓多個線程分塊下載一個大文件,每個線程只下載固定的一截,最後由另外一個線程來拼接所有的分段,那麼這時候我們可以考慮使用CountDownLatch來控制併發
二、CountDownLatch例子
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Created by zhengyong on 16/8/22.
*/
public class CountDownLatchTest {
public static void main(String[] args) {
System.out.println("main start.");
CountDownLatch countDownLatch = new CountDownLatch(3);
ExecutorService executorService = Executors.newFixedThreadPool(3);
ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<>();
executorService.execute(new TaskService(countDownLatch, resultMap, "first"));
executorService.execute(new TaskService(countDownLatch, resultMap, "second"));
executorService.execute(new TaskService(countDownLatch, resultMap, "third"));
try {
countDownLatch.await(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.shutdown();
System.out.println("main finish.");
for (String key : resultMap.keySet()) {
System.out.println(String.format("key=%s; value=%s", key, resultMap.get(key)));
}
}
static class TaskService implements Runnable {
private CountDownLatch countDownLatch;
private ConcurrentHashMap<String, Object> resultMap;
private String param;
public TaskService(CountDownLatch countDownLatch, ConcurrentHashMap<String, Object> resultMap, String param){
this.countDownLatch = countDownLatch;
this.resultMap = resultMap;
this.param = param;
}
@Override
public void run() {
try {
System.out.println("execute task begin.");
resultMap.put(param, UUID.randomUUID().toString());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("task finish.");
} finally {
System.out.println(String.format("the count down param is %s.", param));
countDownLatch.countDown();
}
}
}
}
運行結果:
main start.
execute task begin.
execute task begin.
execute task begin.
task finish.
task finish.
task finish.
the count down param is second.
the count down param is third.
the count down param is first.
main finish.
key=third; value=8762cdd0-3db7-4e97-a5cb-b7d3344117a0
key=first; value=5782e550-8637-49c5-8e82-7d9ec3d833d0
key=second; value=46cfb2c5-26b4-464d-b399-7d9bdd4ef100