1. 循环栅栏===>发令枪,人满了就推到栅栏,人走光后栅栏就再起来,等人满再次倒下……
  2. 两个参数,第二个参数BarrierAction可以不传,不传表示满员了不做任何操作
  3. 动作可以是一个Runnable对象;也可以用lambda表达式
  4. 来的线程要调用await方法在那等着,直到人满了就进行发车
  5. 这与countDown不光是正数倒数的问题,一个循环一个不循环的问题
    1. countDown可以同一个线程一直countDown,并不一定要不同线程去countDown
    2. countDown是拴在某一个线程中,其他线程什么时候countDown结束了就继续向下
    3. CyclicBarrier是线程在那堆满了(达到标准),才能继续往下执行
  6. 在下面的代码中准确来说是19个线程在那等着,第20个线程一来就满了,就继续向下执行了
  1. package com.mashibing.juc.c_020;
  2. import java.util.concurrent.BrokenBarrierException;
  3. import java.util.concurrent.CyclicBarrier;
  4. public class T07_TestCyclicBarrier {
  5. public static void main(String[] args) {
  6. //CyclicBarrier barrier = new CyclicBarrier(20);
  7. CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println(""));
  8. /*CyclicBarrier barrier = new CyclicBarrier(20, new Runnable() {
  9. @Override
  10. public void run() {
  11. System.out.println("ˣ");
  12. }
  13. });*/
  14. for(int i=0; i<100; i++) {
  15. new Thread(()->{
  16. try {
  17. barrier.await();
  18. } catch (InterruptedException e) {
  19. e.printStackTrace();
  20. } catch (BrokenBarrierException e) {
  21. e.printStackTrace();
  22. }
  23. }).start();
  24. }
  25. }
  26. }

实际应用场景

限流(错误!!!):好多请求一下子打到数据库上,数据库容器宕机,这时要限流===>令牌桶

  • 请求流量的入口特别多,但是后面的出口会被限制住(只有30个请求能过来),可以用CyclicBarrier
  • 但是一般会用Guava RateLimiter(谷歌专门做的用于限流的服务类)

    错误原因:限流的例子有点问题,因为少于20个就能直接过去,而不需要等着;正确的逻辑应该是超过20个的时候,超过20的部分等着,少于20的部分,直接过去

线程同步的时候:比如一个线程需要另外好多个线程的结果(执行结束)时,可以用CyclicBarrier

  • 复杂操作:

-数据库 -网络 -文件 -1、2、3顺序执行,效率太低

  • 并发执行

-不同的线程去执行不同的操作 -有的线程去数据库 -有的数据库去访问网络 -有的线程去访问文件