自己动手简单实现CountDownLatch

来源:互联网 发布:奶酪陷阱同款衣服淘宝 编辑:程序博客网 时间:2024/05/24 02:22

在使用线程池的过程中,如何判断所有提交的任务都已经执行完毕了呢?使用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  0pool-1-thread-5  4pool-1-thread-4  3pool-1-thread-3  2pool-1-thread-2  1All 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  3pool-1-thread-3  2pool-1-thread-5  4pool-1-thread-2  1pool-1-thread-1  0All task finished

无论执行多少次,都能保证所有线程都完成任务后在输出打印语句。

原创粉丝点击