同步工具类之CyclicBarrier

一, CyclicBarrier栅栏简介
  • 栅栏(Barrier)类似闭锁,他能阻塞一组线程直到某个事件发生.栅栏与闭锁的关键区别在于,所有线程必须同时到达栅栏位置,才能继续执行. 闭锁用于等待事件,而栅栏用于等待其他线程.
  • 当所有线程都到达了栅栏位置,那么栅栏将打开,此时所有线程都会被释放,栅栏可以reset以便于下一次复用
  • 如果await的调用超时,或者await阻塞的线程被打断,那么栅栏就被认为是打破了,所有阻塞的await调用都将终止并抛出BrokenBarrierException.如果成功地通过栅栏,那么await将为每个线程返回一个唯一的到达索引号.
  • CyclicBarrier 的构造函数public CyclicBarrier(int parties,Runnable barrierAction)可以传递一个Runnable对象,当成功通过栅栏时会被执行,且由最后一个进入 barrier 的线程执行。
二, CyclicBarrier示例
public class Test {
    private static final int N = 10;

    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier barrier = new CyclicBarrier(N, new Runnable() {

            @Override
            public void run() {
                        //所有线程都到达才会执行,且由最后一个到达的线程执行
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "   所有的任务都已经到达栅栏位置,栅栏打开了   "+System.currentTimeMillis() );
            }

        });
        test(barrier,N);
        test(barrier,N);
    }
    
    private static void test(CyclicBarrier barrier,int nThread) throws InterruptedException{
        for(int i=0; i< nThread-1; i++){
            CyclicBarrierThread t = new CyclicBarrierThread(barrier);
            t.start();
        }
        
        try {
            barrier.await();
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
        Thread.sleep(1000);
        System.out.println(Thread.currentThread().getName() + "   所有子任务执行完毕  "+System.currentTimeMillis());
        System.out.println("******************************************");
              //重置以便于复用
        barrier.reset();
    }
}

class CyclicBarrierThread extends Thread {
    CyclicBarrier barrier;

    CyclicBarrierThread(CyclicBarrier barrier) {
        this.barrier = barrier;
    }

    @Override
    public void run() {
        try {
            barrier.await();
            System.out.println(Thread.currentThread().getName() + "   执行了 "+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

参考:
<>

你可能感兴趣的:(同步工具类之CyclicBarrier)