写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!
概念:
CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之后,再继续执行。使用一个计数器进行实现。计数器初始值为线程的数量。当每一个线程完成自己任务后,计数器的值就会减一。当计数器的值为0时,表示所有的线程都已经完成一些任务,然后在CountDownLatch上等待的线程就可以恢复执行接下来的任务。
主要方法:
1.public void await() throws InterruptedException { };
调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行。
2.public boolean await(long timeout, TimeUnit unit) throws InterruptedException { };
和await()类似,只不过等待一定的时间后count值还没变为0的话就会继续执行。
3.public void countDown() { };
将count值减1。
场景一:
一个线程需要等待其它线程执行完才执行。
public class CountDownLatchTest {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
CountDownLatch countDownLatch = new CountDownLatch(3);
Task1 task1 = new Task1(countDownLatch);
executorService.execute(task1);
for (int i=0;i<3;i++){
Task2 task2 = new Task2(countDownLatch);
executorService.execute(task2);
}
// 关闭线程池
executorService.shutdown();
}
static class Task1 implements Runnable{
private CountDownLatch countDownLatch;
public Task1(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + "等待其它线程执行完毕");
countDownLatch.await();
System.out.println(Thread.currentThread().getName() + "其它线程执行完毕");
mainTask();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static class Task2 implements Runnable{
private CountDownLatch countDownLatch;
public Task2(CountDownLatch countDownLatch){
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
System.out.println("子任务" + Thread.currentThread().getName() + "开始执行");
Thread.sleep(2000);
System.out.println("子任务" + Thread.currentThread().getName() + "执行完毕");
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
static void mainTask(){
System.out.println("111111");
}
}
执行结果如下:
可以看出pool-1-thread-1这个线程一直等到其它线程都执行完了才执行mainTask()方法打印111111。
开发过程中会经常遇到这种情况,我先要返回一个结果,但是返回的结果信息需要从不同的表中查询或者调用不同的服务获取后再拼装才能得到,这中情况是场景一在开发中最常见的了。