CyclicBarrier概念:
CyclicBarrier是多线程中的一个同步工具,它允许一组线程互相等待,直到到达某个公共屏障点。形象点儿说,CyclicBarrier就是一个屏障,要求这一组线程中的每一个线程都要等待其他的线程执行完成,即这一组线程全部来到屏障前(全部执行完成),屏障才会打开,放这一组线程全部通过去执行下一个操作。
构造方法:
- CyclicBarrier(int parties):需要声明需要拦截的线程数;
- CyclicBarrier(int parties, Runnable barrierAction) :需要定义一个等待所有线程到达屏障优先执行的Runnable对象。
主要方法:
- awit():线程等待,在CyclicBarrier对象上调用一次parties减1,直到减到0,就全部线程进行下一个操作。
- getNumberWaiting():返回当前等待的线程数,从0开始。
- getParties():返回总的能拦截的线程数。
示例:
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 implements Runnable { CyclicBarrier barrier = new CyclicBarrier(4); @Override public void run() { try { Thread.sleep(new Random().nextInt(1000)); } catch (InterruptedException e1) { e1.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "已准备"); try { if (barrier.getNumberWaiting() + 1 == barrier.getParties()) { System.out.println("对局开始"); } else { System.out.println("请等待"); } barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(4); CyclicBarrierDemo cbd = new CyclicBarrierDemo(); for (int i = 0; i < 4; i++) { service.execute(cbd); } service.shutdown(); } }
下面,我们看一看结果:
最后,总结一下CyclicBarrier和CountDownLatch的区别:
1)CountDownLatch是一个或多个线程,等待另外N个线程完成某个事情之后才能执行;CyclicBarrier是N个线程相互等待,任何一个线程完成之前,所有的线程都必须等待。
2)CountDownLatch是一次性的,不可重用;CyclicBarrier可以重复使用。
3)CountDownLatch基于AQS;CyclicBarrier基于锁和Condition。