24.循环栅栏 CyclicBarrier

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

/**
 * 循环栅栏 CyclicBarrier
 * 可以反复使用的计数器
 * 如:计数器设置为10,凑齐第一批10个线程后,计数器就会归零,然后接着凑齐下一批10个线程
 *
 *  public CyclicBarrier(int parties, Runnable barrierAction) //计数总数,线程总数
 */
public class CyclicBarrierDemo {
    public static class Soldier implements Runnable{
        private String soldier;
        private final CyclicBarrier cyclicBarrier;
        Soldier(String soldierName, CyclicBarrier cyclicBarrier) {
            this.soldier = soldierName;
            this.cyclicBarrier = cyclicBarrier;
        }
        @Override
        public void run() {
            try {
                //等待任务安排
                System.out.println("开始了");
                cyclicBarrier.await();
                doWork();
                //等待任务完成
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                //InterruptedException线程被中断
                //BrokenBarrierException:表示当前的cyclicBarrier已经破损了,避免其他线程进行永久的,无所谓的等待
                e.printStackTrace();
            }
        }

        void doWork() {
            try {
                Thread.sleep(Math.abs(new Random().nextInt()%10000));
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(soldier+":任务完成");
        }
    }
    public static class BarrierRun implements Runnable{
        boolean  flag;
        int N;

        public BarrierRun(boolean flag, int n) {
            this.flag = flag;
            N = n;
        }

        @Override
        public void run() {
            if (flag){
                System.out.println(N+"个任务已完成!");
            }else {
                System.out.println("安排"+N+"个任务!");
                flag = true;
            }
        }
    }
    public static void main(String[] args){
        final int N = 10;
        Thread[] allSoldier = new Thread[10];
        boolean flag = false;
        CyclicBarrier cyclic = new CyclicBarrier(N, new BarrierRun(flag, N));
        System.out.println("安排任务...");
        for (int i = 0; i < N; i++) {
            System.out.println("任务"+i+"安排");
            allSoldier[i] = new Thread(new Soldier("任务"+i,cyclic));
            allSoldier[i].start();
        }
    }
    //每运行完N个次数的任务就会执行BarrierRun任务

    //安排任务...
    //任务0安排
    //任务1安排
    //开始了
    //开始了
    //任务2安排
    //开始了
    //任务3安排
    //开始了
    //任务4安排
    //任务5安排
    //开始了
    //任务6安排
    //开始了
    //任务7安排
    //开始了
    //任务8安排
    //开始了
    //开始了
    //任务9安排
    //开始了
    //安排10个任务!
    //任务6:任务完成
    //任务3:任务完成
    //任务9:任务完成
    //任务5:任务完成
    //任务4:任务完成
    //任务0:任务完成
    //任务8:任务完成
    //任务7:任务完成
    //任务2:任务完成
    //任务1:任务完成
    //10个任务已完成!
}

猜你喜欢

转载自www.cnblogs.com/fly-book/p/11403481.html
今日推荐