zoukankan      html  css  js  c++  java
  • 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个任务已完成!
    }
    
  • 相关阅读:
    SNMP简介
    命令模式
    牛顿法
    仿射函数
    schedule
    命令模式
    牛顿法
    schedule
    仿射函数
    适配器模式
  • 原文地址:https://www.cnblogs.com/fly-book/p/11403481.html
Copyright © 2011-2022 走看看