首页 > 代码库 > java CyclicBarrier的介绍和使用

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线程

java CyclicBarrier的介绍和使用