线程屏障使用 CyclicBarrier

http://blog.csdn.net/gongpulin/article/details/51236398

线程方法中获取CyclicBarrier实例,使用await方法,设置屏障点,当CyclicBarrier的所有实例都到达await再继续执行线程。CyclicBarrier(需要拦截的线程数量,Runable->当所有线程都到达拦截点是触发这个runable)
作者:xndxcsd链接:https://www.nowcoder.com/discuss/29617?type=2&order=0&pos=14&page=1来源:牛客网多线程应用题,
五个运动员(相当于五个线程)一个裁判(相当于主线程),满足一下3个条件,如何实现:
1.要同时起跑
2.要所有运动员都到达终点以后才能进行下一个环节
3.如果有一个运动员摔跤了(异常处理),就终止这次比赛,让所有运动员都到终点进行下一个环节。

package test;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

public class CyclicBarrierTest {

    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new BarrierRunable());
        TestRunable test = new TestRunable(cyclicBarrier);
        Thread p1 = new Thread(test);
        Thread p2 = new Thread(test);
        Thread p3 = new Thread(new Test2Runable(cyclicBarrier, 1));
        p1.start();
        p2.start();
        p3.start();
    }

}
class BarrierRunable implements Runnable{
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + "-thread:全部到达!");
    }
    
}
class TestRunable implements Runnable{
    CyclicBarrier cyclicBarrier;
    public TestRunable(CyclicBarrier cb) {
        this.cyclicBarrier = cb;
    }

    @Override
    public void run() {
        try {
            //等待前
            Thread.sleep((long) (10000 + Math.random()));
            System.out.println(Thread.currentThread().getName() + "-thread:已准备!" + "->前面有" + cyclicBarrier.getNumberWaiting() + "人准备好了");
            cyclicBarrier.await();
            
            System.out.println(Thread.currentThread().getName() + "-thread:开始跑!");
            Thread.sleep((long) (10000 + Math.random()));
            System.out.println(Thread.currentThread().getName() + "-thread:到达终点");
            cyclicBarrier.await();
            System.out.println(Thread.currentThread().getName() + "-thread:准备下一个任务");
        } catch (InterruptedException | BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
    
}

class Test2Runable implements Runnable{
    CyclicBarrier cyclicBarrier;
    int flag;
    public Test2Runable(CyclicBarrier cb, int flag) {
        this.cyclicBarrier = cb;
        this.flag = flag;
    }

    @Override
    public void run() {
        try {
            //等待前
            Thread.sleep((long) (10000 + Math.random()));
            System.out.println(Thread.currentThread().getName() + "-thread:已准备!" + "->前面有" + cyclicBarrier.getNumberWaiting() + "人准备好了");
            cyclicBarrier.await();
            
            System.out.println(Thread.currentThread().getName() + "-thread:开始跑!");
            if(flag == 1){
                throw new Exception("错误");
            }
            Thread.sleep((long) (10000 + Math.random()));
            System.out.println(Thread.currentThread().getName() + "-thread:到达终点");
            cyclicBarrier.await();
            System.out.println(Thread.currentThread().getName() + "-thread:准备下一个任务");
        } catch (Exception e) {
            //e.printStackTrace();
            System.out.println(Thread.currentThread().getName() + "-thread:我不跑了");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (BrokenBarrierException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }
    }
    
}

你可能感兴趣的:(线程屏障使用 CyclicBarrier)