学习多线程之CyclicBarrier使用

94 阅读2分钟

「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战

写在前面

今天我们来学习多线程中CyclicBarrier工具,其含义是一个可循环使用的屏障工具,有点像上篇文章中所讲到的CountDownLatch工具类,下面就一起来看看到底是哪里有些不同吧。

学习多线程之CyclicBarrier使用

CyclicBarrier工具,特征主要是有这么两点。

其一是可循环使用,不像是CountDownLatch的对象,只能使用一次,这个工具没有数量等条件的限制,有的只是支持的线程数参数而已,所以也就可以循环使用了。

其二是提供了屏障的效果,可以使得多个线程同时在屏障处实现等待的效果,只有所有的线程都处于屏障处的效果,才可以同时继续往下运行。

当然了,要理解这个工具的使用,还需要一个代码示例才能解决,来看一下如下的代码吧:

public static void main(String[] args) {
    Thread thread = new Thread(new Runnable() {
        @SneakyThrows
        @Override
        public void run() {
            System.out.println("所有的线程都已准备好,开始运行主线程"+System.currentTimeMillis());
        }
    });
    CyclicBarrier cyclicBarrier = new CyclicBarrier(4, thread);
    Thread thread0 = new Thread(new Runnable() {
        @SneakyThrows
        @Override
        public void run() {
            System.out.println("thread0运行ing"+System.currentTimeMillis());
            cyclicBarrier.await();
        }
    });
    Thread thread1 = new Thread(new Runnable() {
        @SneakyThrows
        @Override
        public void run() {
            System.out.println("thread1运行ing"+System.currentTimeMillis());
            cyclicBarrier.await();
        }
    });
    Thread thread2 = new Thread(new Runnable() {
        @SneakyThrows
        @Override
        public void run() {
            System.out.println("thread2运行ing"+System.currentTimeMillis());
            cyclicBarrier.await();
        }
    });
    Thread thread3 = new Thread(new Runnable() {
        @SneakyThrows
        @Override
        public void run() {
            System.out.println("thread3运行ing"+System.currentTimeMillis());
            Thread.sleep(3000);
            cyclicBarrier.await();
        }
    });
    thread0.start();
    thread1.start();
    thread2.start();
    thread3.start();
}

这段代码的执行结果如下所示:

thread1运行ing1645933806635

thread2运行ing1645933806635

thread0运行ing1645933806635

thread3运行ing1645933806635

所有的线程都已准备好,开始运行主线程1645933809636

如果你看过上一篇文章的话,就会知道今天的代码大同小异。

还是来解释一下,CyclicBarrier的使用,要传入两个参数,一个参数是线程数,另一个参数是等待所有线程到达屏障处要执行的线程任务。

从上面的代码中,我们得到了预期的结果,那就是thread线程等待了所有线程都准备好了才开始执行自己线程。

这一点大家也可以去自行试一下。