CyclicBarrier类:
原文:一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环的 barrier。CyclicBarrier支持一个可选的 Runnable 命令,在一组线程中的最后一个线程到达之后(但在释放所有线程之前),该命令只在每个屏障点运行一次。若在继续所有参与线程之前更新共享状态,此屏障操作 很有用。
说人话:它可以让多个线程阻塞,调用CyclicBarrier的await()方法让线程一直在等待,直到所有线程都到达屏障后再唤醒。
CyclicBarrier提供2个构造方法:
CyclicBarrier(int parties)
CyclicBarrier(int parties, Runnable barrierAction)
下面的例子使用第二个构造方法,模拟10个狙击手分别就位,如果10个狙击手都已经就位完毕,则报告给指挥官,指挥官下达命令后才能进行射击。
public class Demo { public static void main(String[] args) { //定义10个狙击手 int threadNum = 10; //实例化一个CyclicBarrier(循环屏障) CyclicBarrier cyclicBarrier = new CyclicBarrier(threadNum, new Runnable(){ @Override public void run(){ System.out.println("负责人:报告指挥官,所有狙击手已就位完毕。"); System.out.println("指挥官:行动!"); } }); //模拟加入10个线程 for(int i=1; i<=threadNum; i++){ new Thread(new Sniper(cyclicBarrier, "狙击手" + i + "号")).start(); } } }
定义一个狙击手的类,并实现Runnable接口。
public class Sniper implements Runnable { private CyclicBarrier cyclicBarrier; private String name; public Sniper(CyclicBarrier cyclicBarrier, String name){ this.cyclicBarrier = cyclicBarrier; this.name = name; } @Override public void run() { try { //随机0-10秒模拟狙击手就位需要的时间 Random ran = new Random(); int millisecond = (ran.nextInt(10) + 1); int second = millisecond * 1000; Thread.sleep(second); //准备好之后,报告已就位 System.out.println( name + ":已就位,用时" + millisecond + "秒。"); //调用cyclicBarrier.await()方法进行等待 cyclicBarrier.await(); //狙击手打击目标 System.out.println( name + ":报告," + (millisecond % 2 == 1 ? "已击毙敌人。" : "未命中。")); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }
效果如下:
时间: 2024-10-08 12:05:13