在使用线程池的过程中,如何判断所有提交的任务都已经执行完毕了呢?使用jdk自带的CountDownLatch,可以轻松实现这一需求
public class CountdownLatchTest {
private static final CountDownLatch countDownLatch = new CountDownLatch(5);
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
IntStream.range(0, 5).forEach(i -> {
executorService.submit(() -> {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " " + i);
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
});
executorService.shutdown();
countDownLatch.await();
System.out.println("All task finished");
}
}
执行结果
pool-1-thread-1 0
pool-1-thread-5 4
pool-1-thread-4 3
pool-1-thread-3 2
pool-1-thread-2 1
All task finished
利用CountDownLatch作为一个计数器,当所有线程完成任务时,调用countDown方法。调用await方法,会阻塞当前线程,直到所有任务都已完成。
所以在输出结果中,All task finished永远在线程任务都完成后。
现在自己简单实现这一功能。
public class CountDown {
private final int total;
private int count = 0;
public CountDown(int count) {
this.total = count;
}
public void countDown() {
synchronized (this) {
count++;
this.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (this) {
while (count != total) {
this.wait();
}
}
}
}
定义CountDown类,有两个属性total和count。total记录所有线程的数量,count记录当前完成线程的数量。count和total不相等时,wait,在countdown时唤醒,直到total和count相等时退出循环。
测试
public class CountDownTest {
private static final CountDown countDownLatch = new CountDown(5);
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
IntStream.range(0, 5).forEach(i -> {
executorService.submit(() -> {
try {
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " " + i);
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
});
executorService.shutdown();
countDownLatch.await();
System.out.println("All task finished");
}
}
结果
pool-1-thread-4 3
pool-1-thread-3 2
pool-1-thread-5 4
pool-1-thread-2 1
pool-1-thread-1 0
All task finished
无论执行多少次,都能保证所有线程都完成任务后在输出打印语句。