多线程之CyclicBarrier

多线程之CyclicBarrier

CyclicBarrier

Barriers are similar to latches in that they block a group of threads until some event has occurred [CPJ 4.4.3]. The key difference is that with a barrier, all the threads must come together at a barrier point at the same time in order to proceed.

useful in parallel iterative algorithms that break down a problem into a fixed number of independent subproblems.

Threads call await when they reach the barrier point, and await blocks until all the threads have reached the barrier point. If all threads meet at the barrier point, the barrier has been successfully passed, in which case all threads are released and the barrier is reset so it can be used again

If a call to await times out or a thread blocked in await is interrupted, then the barrier is considered broken and all outstanding calls to await terminate with BrokenBarrierException

If the barrier is successfully passed, await returns a unique arrival index for each thread, which can be used to “elect” a leader that takes some special action in the next iteration.

CyclicBar rier also lets you pass a barrier action to the constructor; this is a Runnable that is executed (in one of the subtask threads) when the barrier is successfully passed but before the blocked threads are released.

CyclicBarrier要做的事情是让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程一起执行。

CyclicBarrier(int parties):构造方法,parties表示拦截线程的数量。

CyclicBarrier(int parties, Runnable barrierAction) :barrierAction用于在线程到达屏障时优先执行b,用于处理更加复杂的业务场景。

await():将当前线程阻塞,等到所有的线程都到达指定的临界点后一起执行。

getNumberWaiting():获取当前有多少个线程阻塞等待在临界点上。

reset():将屏障重置为初始状态。

例子

8个运动员参加比赛,运动员可能到达赛场的时间不一样,要等8个运动员到齐了才开始比赛,

public class CyclicBarrierTest {
private static CyclicBarrier barrier = new CyclicBarrier(8, () -> {
System.out.println("所有运动员入场,裁判员一声令下!!!");
});

public static void main(String[] args) {
System.out.println("运动员准备进场,全场欢呼......");

for (int i = 0; i < 8; i++) {
new Thread() {
public void run() {
System.out.println(Thread.currentThread().getName() + " 运动员到达起点,准备好了!!!");
try {
barrier.await();// 运动员等待,等所有运动员全部到齐后一起开始比赛
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 运动员出发!!!");

};
}.start();
}
}
}

CyclicBarrier与 countdownLatch 区别

  1. CountDownLatch用于一个线程等待若干个其他线程执行完任务之后才执行,强调一个线程等待,这个线程会阻塞。而CyclicBarrier用于一组线程互相等待至某个状态,然后这一组线程再同时执行,强调的是多个线程互等,这多个线程阻塞,等大家都完成,再携手共进。
  2. CountDownLatch是不能复用的,而CyclicLatch是可以复用的。使用reset()方法将屏障重置为初始状态之后就可以复用。
  3. CyclicBarrier提供了更多的方法,能够通过getNumberWaiting()获取阻塞线程的数量,通过isBroken()方法可以知道阻塞的线程是否被中断。

https://mp.weixin.qq.com/s?__biz=MzAxMjEwMzQ5MA==&mid=2448890739&idx=3&sn=2843b5db35ad1704d32c61b2fc51bfc7&scene=21#wechat_redirect