• 24.循环栅栏 CyclicBarrier


    
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    /**
     * CyclicBarrier可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。 
     */
    public class CyclicBarrierDemo extends Thread {
        private CyclicBarrier cyclicBarrier;
        public CyclicBarrierDemo(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
    
        @Override
        public void run() {
            System.out.println("子线程,"+Thread.currentThread().getName()+ " 开始写...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("子线程,"+Thread.currentThread().getName()+ " 写完成...");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println("所有线程执行完毕...");
        }
        public static void main(String[] args){
            CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
            for (int i = 0; i < 5; i++) {
                CyclicBarrierDemo writer = new CyclicBarrierDemo(cyclicBarrier);
                writer.start();
            }
        }
        //子线程,Thread-0 开始写...
        //子线程,Thread-1 开始写...
        //子线程,Thread-2 开始写...
        //子线程,Thread-3 开始写...
        //子线程,Thread-4 开始写...
        //子线程,Thread-1 写完成...
        //子线程,Thread-0 写完成...
        //子线程,Thread-2 写完成...
        //子线程,Thread-4 写完成...
        //子线程,Thread-3 写完成...
        //所有线程执行完毕...
        //所有线程执行完毕...
        //所有线程执行完毕...
        //所有线程执行完毕...
        //所有线程执行完毕...
    }
    
    
    
    /**
     * Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行
     */
    public class CyclicBarrierDemo extends Thread {
        private CyclicBarrier cyclicBarrier;
        public CyclicBarrierDemo(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }
    
        @Override
        public void run() {
            System.out.println("子线程,"+Thread.currentThread().getName()+ " 开始写...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("子线程,"+Thread.currentThread().getName()+ " 写完成...");
            try {
                cyclicBarrier.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println("所有线程执行完毕...");
        }
        public static void main(String[] args){
            CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
                @Override
                public void run() {
                    System.out.println("完成一个小目标");
                }
            });
            for (int i = 0; i < 5; i++) {
                CyclicBarrierDemo writer = new CyclicBarrierDemo(cyclicBarrier);
                writer.start();
            }
        }
        //子线程,Thread-0 开始写...
        //子线程,Thread-1 开始写...
        //子线程,Thread-2 开始写...
        //子线程,Thread-3 开始写...
        //子线程,Thread-4 开始写...
        //子线程,Thread-0 写完成...
        //子线程,Thread-2 写完成...
        //子线程,Thread-3 写完成...
        //子线程,Thread-4 写完成...
        //子线程,Thread-1 写完成...
        //完成一个小目标
        //所有线程执行完毕...
        //所有线程执行完毕...
        //所有线程执行完毕...
        //所有线程执行完毕...
        //所有线程执行完毕...
    }
    
    
    import java.util.Random;
    import java.util.concurrent.BrokenBarrierException;
    import java.util.concurrent.CyclicBarrier;
    
    /**
     * CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在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个任务已完成!
    }
    
  • 相关阅读:
    缩点【洛谷P1262】 间谍网络
    模板-割点
    Tarjan缩点+LCA【洛谷P2416】 泡芙
    模拟赛 10-20考试记
    BFS【bzoj1667】: [Usaco2006 Oct]Cows on Skates滑旱冰的奶牛
    最短路【bzoj2464】: 中山市选[2009]小明的游戏
    linux /dev/mapper/centos-root 被占满
    Centos7中安装Mysql8并修改密码策略并远程连接
    Centos7中PHP编译安装mysqli扩展报错
    Linux中Composer 在安装依赖包与本地php版本不符问题
  • 原文地址:https://www.cnblogs.com/fly-book/p/11403481.html
Copyright © 2020-2023  润新知