【并发编程】- CyclicBarrier的使用

204 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第16天,点击查看活动详情

CyclicBarrier的使用

实现所有线程都到达同步点时再继续运行

线程执行代码如下:

public class ThreadA implements Runnable {

    private CyclicBarrier cyclicBarrier;

    public ThreadA(CyclicBarrier cyclicBarrier){
        super();
        this.cyclicBarrier=cyclicBarrier;
    }

    @Override
    public void run() {
        try {
            Thread.sleep((int)Math.random()*1000);
            System.out.println(Thread.currentThread().getName()+"到了!"+System.currentTimeMillis());
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

运行类代码如下:

public class CyclicBarrierRun {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                System.out.println("全部到齐了!");
            }
        });
        ThreadA[] threadAS = new ThreadA[5];
        for (int i = 0; i <threadAS.length ; i++) {
            threadAS[i]=new ThreadA(cyclicBarrier);
        }
        for (int i = 0; i < threadAS.length; i++) {
            new Thread(threadAS[i]).start();
        }
    }
}

运行结果如下:

Thread-1到了!1650275508172
Thread-0到了!1650275508173
Thread-4到了!1650275508172
Thread-3到了!1650275508172
Thread-2到了!1650275508172
全部到齐了!

运行类设置CyclicBarrier设置最大为5个的parties同行者,就是5个线程都执行了cyclicBarrier对象的await()方法后程序才可以继续向下执行,否则这些线程彼此相互等待,一直呈阻塞状态。

那线程个数大于parties数量时能不能分批进行处理呢?

线程执行代码如下:

public class BigPartiesThread implements Runnable {

    private CyclicBarrier cyclicBarrier;

    public BigPartiesThread(CyclicBarrier cyclicBarrier){
        super();
        this.cyclicBarrier=cyclicBarrier;
    }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName()+"开始时间:"+System.currentTimeMillis()+"等待凑齐2个线程继续运行!");
            cyclicBarrier.await();
            System.out.println(Thread.currentThread().getName()+"结束时间:"+System.currentTimeMillis()+"已经凑齐2个线程继续运行!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

运行类代码如下:

public class CyclicBarrierBigPartiesRun {
    public static void main(String[] args) throws InterruptedException {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(2, new Runnable() {
            @Override
            public void run() {
                System.out.println("全部到齐了!");
            }
        });
        BigPartiesThread[] threadAS = new BigPartiesThread[4];
        for (int i = 0; i <threadAS.length ; i++) {
            threadAS[i]=new BigPartiesThread(cyclicBarrier);
            new Thread(threadAS[i]).start();
            Thread.sleep(2000);
        }
    }
}

运行结果如下:

Thread-0开始时间:1650276369239等待凑齐2个线程继续运行!
Thread-1开始时间:1650276371250等待凑齐2个线程继续运行!
全部到齐了!
Thread-1结束时间:1650276371251已经凑齐2个线程继续运行!
Thread-0结束时间:1650276371251已经凑齐2个线程继续运行!
Thread-2开始时间:1650276373265等待凑齐2个线程继续运行!
Thread-3开始时间:1650276375278等待凑齐2个线程继续运行!
全部到齐了!
Thread-3结束时间:1650276375279已经凑齐2个线程继续运行!
Thread-2结束时间:1650276375279已经凑齐2个线程继续运行!