CyclicBarrier可以实现多个线程互相的等待,当每个线程到达某个点的时候,会阻塞直到所有的线程都完成之后,才继续执行
CyclicBarrier和上次介绍的CountDownLatch有点类似,但是也有不同,主要不同点如下:
- CyclicBarrier是多个线程互相等待,CountDownLatch是一个线程等待多个线程
- CyclicBarrier可以重复使用,而CountDownLatch不可以
用法和CountDownLatch类似,有这样的情景:现在需要多个线程进行一项统计任务,每个线程统计完后,需要等待别的线程完成之后,才会继续执行本线程的汇总任务,看下代码
public class CyclicBarrierTest {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
Thread t = new Thread(new Task(barrier));
t.start();
}
}
}
class Task implements Runnable {
private CyclicBarrier barrier;
public Task(CyclicBarrier barrier) {
this.barrier = barrier;
}
@Override
public void run() {
try {
Thread.sleep((int) (Math.random() * 10) * 1000);
System.out.println("线程" + Thread.currentThread().getName() + "结束统计任务 ,等待其他线程完成....");
barrier.await();// 调用该方法之后,将会停止运行,直到其他线程都完成才继续往下运行
Thread.sleep((int) (Math.random() * 10) * 1000);
System.out.println("线程" + Thread.currentThread().getName() + "开始进行汇总....");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
// 结果如下
// 线程Thread-2结束统计任务 ,等待其他线程完成....
// 线程Thread-1结束统计任务 ,等待其他线程完成....
// 线程Thread-3结束统计任务 ,等待其他线程完成....
// 线程Thread-0结束统计任务 ,等待其他线程完成....
// 线程Thread-4结束统计任务 ,等待其他线程完成....
// 线程Thread-1开始进行汇总....
// 线程Thread-0开始进行汇总....
// 线程Thread-4开始进行汇总....
// 线程Thread-2开始进行汇总....
// 线程Thread-3开始进行汇总.... 调用了CyclicBarrier的await方法之后,该线程会等到其他线程都到达这个点,如果所有线程到达了则继续往下运行,如果没有全部到达,则继续等待
再看另外的例子,加深一下印象:现在有一个会议,会议需要在所有人都到达之后,才会开始,会议开始后,所有人才可以进行发言
看下代码
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(5, new Conference());
for (int i = 0; i < 5; i++) {
new Thread(new Paticipant(barrier, "参与者" + i)).start();
}
}
public static class Paticipant implements Runnable {
private CyclicBarrier barrier;
private String name;
public Paticipant(CyclicBarrier barrier, String name) {
this.barrier = barrier;
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep((int) (Math.random() * 10) * 1000);
System.out.println(name + "到达....");
barrier.await();
Thread.sleep((int) (Math.random() * 10) * 1000);
System.out.println(name + "进行发言");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public static class Conference implements Runnable {
@Override
public void run() {
System.out.println("所有人到齐,会议开始,参与者发言论");
}
}
}
// 结果如下
// 参与者2到达....
// 参与者3到达....
// 参与者0到达....
// 参与者4到达....
// 参与者1到达....
// 所有人到齐,会议开始,参与者发言论
// 参与者4进行发言
// 参与者3进行发言
// 参与者1进行发言
// 参与者2进行发言
// 参与者0进行发言 这里CyclicBarrier的构造方法传入了一个Runnable对象,当所有线程都到达的时候,会执行这个对象的run方法,然后再继续运行每个线程的后面的代码
本文介绍了CyclicBarrier在Java并发编程中的应用,通过两个实例详细解释了如何使用CyclicBarrier实现多线程之间的同步等待,包括基本用法及构造方法中传递Runnable对象的场景。

361

被折叠的 条评论
为什么被折叠?



