一步步学习多线程(八) CountDownLatch

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/money9sun/article/details/86686370

CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如火箭发射需要检查很多步,例如10步,每一步都要检查完毕才能发射,这样就可以使用CountDownLatch类来进行。

构造函数:public CountDownLatch(int count) {  };  //参数count为计数值

主要方法:

1、await() 当前线程等待,直到count值为0才继续执行

2、boolean await(long timeout, TimeUnit unit) 与await()类似,但不会一直等待,如果一段时间count值还没有变为0,则继续执行

3、countDown() { };  //将count值减1

例子1:火箭发射的例子,10个准备环节,准备结束后发射

public class RocketTest {

    static CountDownLatch countDownLatch = new CountDownLatch(10);

    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            int finalI = i;
            new Thread(() -> {
                try {
                    Thread.sleep((int)(Math.random()*3000));
                    System.out.println("检查环节" + finalI + "结束");
                    countDownLatch.countDown();  // 每个线程做一个检查,检查完毕就减一
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }

        new Thread(() -> {
            try {
                countDownLatch.await();
                System.out.println("准备完毕,发射");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

    }
}

执行结果

检查环节2结束
检查环节4结束
检查环节9结束
检查环节8结束
检查环节0结束
检查环节7结束
检查环节3结束
检查环节6结束
检查环节5结束
检查环节1结束
准备完毕,发射

例子2:模拟并发

public class CountDownLatchConcurrency {

    static CountDownLatch countDownLatch = new CountDownLatch(10);

    public static void main(String[] args) {

        for (int i = 0; i < 10; i++) {
            int finalI = i;
            new Thread(() -> {
                try {
                    // 每个线程休眠0-2秒
                    Thread.sleep((int)(Math.random()*2000));
                    System.out.println("线程" + finalI + "准备完毕");
                    // 计数器减一
                    countDownLatch.countDown();
                    // 等待其他的线程准备
                    countDownLatch.await();
                    System.out.println("\"线程\" + finalI + \"开始\"");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }

    }
}

执行的结果:

线程1准备完毕
线程5准备完毕
线程8准备完毕
线程2准备完毕
线程4准备完毕
线程6准备完毕
线程7准备完毕
线程3准备完毕
线程0准备完毕
线程9准备完毕
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"
"线程" + finalI + "开始"

猜你喜欢

转载自blog.csdn.net/money9sun/article/details/86686370
今日推荐