Java CyclicBarrier的使用
先说说这个类是用来干嘛的吧:
在集合点的同步:CyclicBarrier是一个同步辅助类,它允许两个或者多个线程在某个点上进行同步。这个类与CountDownLatch类似,也有不同之处:
CountDownLatch | CyclicBarrier |
减计数方式 | 加计数方式 |
计算为0时释放所有等待的线程 | 计数达到指定值时释放所有等待线程 |
计数为0时,无法重置 | 计数达到指定值时,计数置为0重新开始 |
调用countDown()方法计数减一,调用await()方法只进行阻塞,对计数没任何影响 | 调用await()方法计数加1,若加1后的值不等于构造方法的值,则线程阻塞 |
不可重复利用 | 可重复利用 |
好了,说说CyclicBarrier这个类是怎么使用的吧:CyclicBarrier类使用了 一个整型数进行初始化,这个数是需要在某个点上进行同步的线程数。当线程到达指定的点后,它将调用await()等待其他的线程。当线程调用await()方法后,CyclicBarrier类将阻塞这个线程并使之休眠到其他所有线程到达。当最后一个线程调用CyclicBarrier类的await()方法时,CyclicBarrier对象将唤醒所有在等待的线程,然后这些线程将继续执行。
来个小例子,你就明白了:
import java.util.Random;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier barrier = new CyclicBarrier(3);
ExecutorService executor = Executors.newFixedThreadPool(3);
executor.submit(new Thread(new Runner(barrier,"1号选手")));
executor.submit(new Thread(new Runner(barrier,"2号选手")));
executor.submit(new Thread(new Runner(barrier,"3号选手")));
executor.shutdown();
}
}
class Runner implements Runnable{
private CyclicBarrier barrier;
private String name;
public Runner(CyclicBarrier barrier, String name) {
super();
this.barrier = barrier;
this.name = name;
}
@Override
public void run() {
try {
Thread.sleep(1000*(new Random()).nextInt(8));
System.out.println(name + "准备好了....");
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();;
}
System.out.println(name + "起跑!");
}
}
输出结果:
1号选手准备好了....
3号选手准备好了....
2号选手准备好了....
1号选手起跑!
2号选手起跑!
3号选手起跑!