java CyclicBarrier的介绍和使用
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。
举例说明:银行要进行账目录入,以防一个录入出现录入错误,采用两人对同一账目同时录入,以达到校对的效果
伪代码如下:
import java.util.concurrent.BrokenBarrierException; import java.util.concurrent.CyclicBarrier; /** * Created by lv xiao long on 2017/7/16. */ public class Work implements Runnable { private CyclicBarrier barrier; private String msg; public Work(String msg, CyclicBarrier barrier){ this.msg=msg; this.barrier=barrier; } public void run() { while (true) { System.out.print(msg); try { barrier.await(); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } break; } } }
import java.util.concurrent.CyclicBarrier; /** * by lv xiao long * */ public class App { public static void main( String[] args ) { //这里设置公共屏障点为3,两个子线程都到达屏障点后,主线程在放行,进入下账目录入,所以这里设置屏障点数为3 CyclicBarrier cyclicBarrier=new CyclicBarrier(3); Work work=new Work("工作人员A录入完成\n",cyclicBarrier); Thread thread=new Thread(work); thread.start(); work=new Work("工作人员B录入完成\n",cyclicBarrier); thread=new Thread(work); thread.start(); try { cyclicBarrier.await(); System.out.println( "可以开始进行下一账目录入!\n" ); } catch (Exception e) { e.printStackTrace(); } } }
这里CycliBarrer 还有一个高级用法api如下
/** * Creates a new <tt>CyclicBarrier</tt> that will trip when the * given number of parties (threads) are waiting upon it, and which * will execute the given barrier action when the barrier is tripped, * performed by the last thread entering the barrier. * * @param parties the number of threads that must invoke {@link #await} * before the barrier is tripped * @param barrierAction the command to execute when the barrier is * tripped, or {@code null} if there is no action * @throws IllegalArgumentException if {@code parties} is less than 1 */ public CyclicBarrier(int parties, Runnable barrierAction) { if (parties <= 0) throw new IllegalArgumentException(); this.parties = parties; this.count = parties; this.barrierCommand = barrierAction; }
在进行实例化的时候可以现设置一个线程
CyclicBarrier cyclicBarrier=new CyclicBarrier(3,work3);当所有线程达到指定屏障点后启动work3线程