· CyclicBarrierAndCountDownLatch_Demo

  1 package com.miaoshaproject.demo;
  2 
  3 import java.util.Random;
  4 import java.util.concurrent.*;
  5 
  6 /**
  7  * @Author wangshuo
  8  * @Date 2022/5/17, 18:17
  9  * CyclicBarrier / CountDownLatch 小demo
 10  */
 11 public class CyclicBarrierAndCountDownLatch_Demo {
 12 
 13     /*
 14         CyclicBarrier多个线程相互等待,全部执行完毕await()后一起继续运行
 15      */
 16     static class CyclicBarrierDemo implements Runnable {
 17 
 18         //私有CyclicBarrier变量
 19         private CyclicBarrier cyclicBarrier;
 20         private String name;
 21 
 22         //提供构造方法
 23         public CyclicBarrierDemo(CyclicBarrier cyclicBarrier, String name) {
 24             this.cyclicBarrier = cyclicBarrier;
 25             this.name = name;
 26         }
 27 
 28         //重写run方法
 29         @Override
 30         public void run() {
 31             try {
 32                 //让三个线程随机睡眠1-10秒
 33                 Thread.sleep(1000 * new Random().nextInt(10));
 34                 System.out.println(name + "睡醒了 开始等待其他线程");
 35                 cyclicBarrier.await();
 36             } catch (InterruptedException | BrokenBarrierException e) {
 37                 e.printStackTrace();
 38             }
 39             System.out.println(name + " 出发");
 40         }
 41     }
 42 
 43     //测试CyclicBarrierDemo
 44     public static class Race {
 45 
 46         public static void main(String[] args) {
 47             //指定三个线程
 48             CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
 49             //创建一个指定数量的线程池
 50             ExecutorService executor = Executors.newFixedThreadPool(3);
 51             executor.submit(new Thread(new CyclicBarrierDemo(cyclicBarrier, "张三")));
 52             executor.submit(new Thread(new CyclicBarrierDemo(cyclicBarrier, "李四")));
 53             executor.submit(new Thread(new CyclicBarrierDemo(cyclicBarrier, "王五")));
 54             //程序执行完毕,卸磨杀驴
 55             executor.shutdown();
 56         }
 57     }
 58 
 59     /*
 60         CountDownLatch创建时可以指定计数器大小
 61             线程调用await()方法后会
 62                 等待其他线程执行CountDown()将计数器减少至0后再进行执行
 63             线程调用CountDown()方法后会
 64                 将CountDownLatch的计数器减一
 65      */
 66     static class CountDownLatchDemo {
 67 
 68         private static final int N = 10;
 69 
 70         static class WorkerDemo implements Runnable {
 71 
 72             private final CountDownLatch doneSignal;
 73             private final CountDownLatch startSignal;
 74             private int beginIndex;
 75 
 76             //对外提供构造方法
 77             public WorkerDemo(CountDownLatch doneSignal, CountDownLatch startSignal, int beginIndex) {
 78                 this.doneSignal = doneSignal;
 79                 this.startSignal = startSignal;
 80                 this.beginIndex = beginIndex;
 81             }
 82 
 83             @Override
 84             public void run() {
 85 
 86                 try {
 87                     startSignal.await();//因为我们先写的创建线程的方法,为防止线程先执行代码,我们先进行阻塞
 88                     for (int i = 0; i < beginIndex; i++) {
 89                         //想要同步执行可以传一个锁进来在这里lock,在下边unlock
 90                         System.out.println(Thread.currentThread().getName().concat(": ") + i);
 91                     }
 92                 } catch (Exception e) {
 93                     e.printStackTrace();
 94                 } finally {
 95                     doneSignal.countDown();//十个线程都countDown()之后主线程的锁就会解开,随后打印“执行完毕”
 96                 }
 97             }
 98         }
 99 
100         public static void main(String[] args) throws InterruptedException {
101 
102             CountDownLatch doneSignal = new CountDownLatch(N);
103             CountDownLatch startSignal = new CountDownLatch(1);
104             //异步创建十个WorkerDemo线程 让它们分别打印1到十个数字
105             for (int i = 1; i <= N; i++) {
106                 new Thread(new WorkerDemo(doneSignal, startSignal, i), "Thread" + i).start();
107             }
108             startSignal.countDown();//这里打开了开关,十个线程一起执行代码
109             System.out.println("开始执行");
110             doneSignal.await();//这里锁上了
111             System.out.println("执行完毕");
112         }
113     }
114 }