开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第19天,点击查看活动详情
- 栅栏类似于闭锁(CountDownLatch),它能阻塞一组线程直到某个事件的发生。栅栏与闭锁的关键区别在于, 所有的线程必须同时到达栅栏位置,才能继续执行。闭锁用于等待事件,而 栅栏用于等待其他线程。
- CyclicBarrier可以使一定数量的线程反复地在栅栏位置处汇集。 当线程到达栅栏位置时将调用await方法,这个方法将阻塞直到所有线程都到达栅栏位置。 如果所有线程都到达栅栏位置,那么栅栏将打开,此时所有的线程都将被释放,而栅栏将被重置以便下次使用。
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,() -> System.out.println("全部完成"));
for (int i = 0; i < 7; i++) {
final int temp = i + 1;
new Thread(() ->{
System.out.println(Thread.currentThread().getName() + "\t第" + temp + "次");
try {
int await = cyclicBarrier.await();
System.out.println("还剩:" + await);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},"线程" + String.valueOf(i)).start();
}
}
CyclicBarrier 与 CountDownLatch 区别
CountDownLatch是一次性的。CyclicBarrier是可循环利用的CountDownLatch参与的线程的职责是不一样的,有的在倒计时,有的在等待倒计时结束。CyclicBarrier参与的线程职责是一样的
javadoc是这么描述它们的:
- CountDownLatch: A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
- CyclicBarrier : A synchronization aid that allows a set of threads to all wait for each other to reach a common barrier point.
- 从javadoc的描述可以得出: CountDownLatch:一个或者多个线程,等待其他多个线程完成某件事情之后才能执行; CyclicBarrier:多个线程互相等待,直到到达同一个同步点,再继续一起执行。
- 对于CountDownLatch来说,重点是“一个线程(多个线程)等待”,而其他的N个线程在完成“某件事情”之后,可以终止,也可以等待。 而对于CyclicBarrier,重点是多个线程,在任意一个线程没有完成,所有的线程都必须互相等待,然后继续一起执行。 CountDownLatch是计数器,线程完成一个记录一个,只不过计数不是递增而是递减,而CyclicBarrier更像是一个阀门,需要所有线程都到达,阀门才能打开,然后继续执行。 按照这个题目的描述等所有线程都到达了这一个阀门处,再一起执行,此题强调的是,一起继续执行,我认为 选B 比较合理!
- 像上文中CountDownLatch的例子,main线程在等待,其余6个线程任务做完之后,main线程才苏醒干后面的事。因为countdown只会阻塞调用者,其它线程干完任务就可以干其他事。这里的调用者线程就是main线程。
- 像上文中CyclicBarrier的例子,是7个线程互相等待对方,7个任务都完成后,执行注册的回调任务。