java并发-CyclicBarrier-实战应用

来源:互联网 发布:php输出中文乱码 编辑:程序博客网 时间:2024/06/06 18:15
  • CyclicBarrier(循环同步屏障点),没个线程到达屏障点时都会阻塞,直到所有线程都准备好后才会往下执行操作,并且可以重置循环使用。
  • 构造方法:CyclicBarrier(int parties)
    创建一个新的 CyclicBarrier,它将使给定数量的线程处于等待状态,当给定线程都调用了await()方法时,线程们才开始执行任务。
    CyclicBarrier简单例子
package com.xll.cyclicBarrierTest;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class RunTest {    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {        CyclicBarrier barrier = new CyclicBarrier(5);//如果将5换成6将永远也不能执行完毕        for (int i = 0; i < 4; i++) {            Runner r = new Runner(i, barrier);            r.start();        }        System.out.println("比赛开始......");        barrier.await();        Thread.sleep(200); //让所有选手比赛完        System.out.println("比赛结束......");    }}class Runner extends Thread {    private int runnerNO;    private CyclicBarrier barrier;    public Runner(int runnerNO, CyclicBarrier barrier) {        this.runnerNO = runnerNO;        this.barrier = barrier;    }    @Override    public void run() {        System.out.println(runnerNO + "选手已经准备好......");        try {            //等于零表示,指定数量的线程调用了await()方法            barrier.await();        } catch (InterruptedException | BrokenBarrierException e) {            e.printStackTrace();        }        System.out.println(runnerNO + "选手比赛完毕!");    }}

执行结果图
这里写图片描述
CyclicBarrier还提供一个更高级的构造函数CyclicBarrier(int parties, Runnable barrierAction),用于在线程到达屏障时,优先执行barrierAction(也就是该线程比其他线程先执行),方便处理更复杂的业务场景。可以用这个来做一些汇总工作的应用,多个线程处理,最后交给barrierAction线程汇总,具体代码如下:

```package com.xll.cyclicBarrierTest;import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;public class RunTest {    public static void main(String[] args) throws InterruptedException, BrokenBarrierException {        CyclicBarrier barrier = new CyclicBarrier(4 , new Runnable(){            @Override            public void run() {                System.out.println("所有选手准备完毕!");            }           });//如果将5换成6将永远也不能执行完毕        for (int i = 0; i < 4; i++) {            Runner r = new Runner(i, barrier);            r.start();        }        System.out.println("比赛开始......");        barrier.await();        Thread.sleep(200); //让所有选手比赛完        System.out.println("比赛结束......");    }}class Runner extends Thread {    private int runnerNO;    private CyclicBarrier barrier;    public Runner(int runnerNO, CyclicBarrier barrier) {        this.runnerNO = runnerNO;        this.barrier = barrier;    }    @Override    public void run() {        System.out.println(runnerNO + "选手已经准备好......");        try {            //等于零表示,指定数量的线程调用了await()方法            barrier.await();        } catch (InterruptedException | BrokenBarrierException e) {            e.printStackTrace();        }        System.out.println(runnerNO + "选手比赛完毕!");    }}

输出结果:
这里写图片描述
从输出中可以看到,“所有选手准备完毕!”,首先输出,然后才输出“选手比赛完毕!”

0 0