Java多线程11:CyclicBarrier组件的详细介绍——学习方腾飞Java并发编程的艺术

CyclicBarrier

CyclicBarrier: 循环屏障,效果是让多个线程在这个屏障前等待(await()方法之前),当所有线程都执行到了这个位置时,再一起继续执行后面的动作。

CyclicBarrier的一个例子

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;

/**
 * @author fitz.bai
 */
public class MyThread15 {
    private static CyclicBarrier cyclicBarrier;
    private static int SIZE = 5;

    public static void main(String[] args) {
        cyclicBarrier = new CyclicBarrier(SIZE, () -> System.out.println("执行的是线程" + Thread.currentThread().getName()));
        for (int i = 0; i < SIZE; i++) {
            new InnerThread().start();
        }
    }


    private static class InnerThread extends Thread {
        @Override
        public void run() {
            try {
                System.out.println(Thread.currentThread().getName() + "开始等待,时间为" + System.currentTimeMillis());
                cyclicBarrier.await();
                System.out.println(Thread.currentThread().getName() + "结束了,时间为" + System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
        }
    }
}
//执行结果
Thread-1开始等待,时间为1533561127898
Thread-0开始等待,时间为1533561127898
Thread-2开始等待,时间为1533561127899
Thread-4开始等待,时间为1533561127900
Thread-3开始等待,时间为1533561127899
执行的是线程Thread-3
Thread-1结束了,时间为1533561127960
Thread-2结束了,时间为1533561127960
Thread-4结束了,时间为1533561127961
Thread-0结束了,时间为1533561127961
Thread-3结束了,时间为1533561127960

结论:

我们看到,在执行线程之前5个线程执行的全是await()方法之前的代码,之后Thread-3执行了CyclicBarrier对象里的线程的方法,这里有人说是随机一个线程去执行构造器里面的代码,但是我多次测试都是最后一个打印出来的线程,比如这里就是Thread-3执行,不知道是不是巧合,后续将会看一下源码,研究一下是不是最后到达的线程进行执行(TODO)。当所有线程都到达屏障前的时候,就再执行屏障后的代码

CyclicBarrier和CountDownLatch

发现CyclicBarrier和CountDownLatch还是有一些类似的感觉,但是又不一样
区别:
1、CountDownLatch是在多个线程都进行了countDown()后才会触发事件,唤醒await()在latch上的线程。执行countDown()的线程,执行完countDown()后会继续自己线程的工作;CyclicBarrier是一个栅栏,用于同步所有调用await()方法的线程,线程执行了await()方法之后并不会执行之后的代码,而只有当执行await()方法的线程数等于指定的parties之后,这些执行了await()方法的线程才会同时运行。一种感觉就是,CountDownLatch是当一些线程满足条件之后去唤醒其它睡着的线程,而CyclicBarrier是当指定数量的线程都执行到等待之后,再去执行各自后续的任务。
2、CountDownLatch不能循环使用,计数器减为0就减为0了,不能被重置;CyclicBarrier提供了reset()方法,支持循环使用
3、CountDownLatch当调用countDown()方法使计数器等0时,随后可以唤起多条线程;CyclicBarrier当执行await()方法的线程等于指定的SIZE之后,只能唤起一个BarrierAction

猜你喜欢

转载自blog.csdn.net/qq_22798455/article/details/81461675