- 循环栅栏===>发令枪,人满了就推到栅栏,人走光后栅栏就再起来,等人满再次倒下……
- 两个参数,第二个参数BarrierAction可以不传,不传表示满员了不做任何操作
- 动作可以是一个Runnable对象;也可以用lambda表达式
- 来的线程要调用await方法在那等着,直到人满了就进行发车
- 这与countDown不光是正数倒数的问题,一个循环一个不循环的问题
- countDown可以同一个线程一直countDown,并不一定要不同线程去countDown
- countDown是拴在某一个线程中,其他线程什么时候countDown结束了就继续向下
- CyclicBarrier是线程在那堆满了(达到标准),才能继续往下执行
- 在下面的代码中准确来说是19个线程在那等着,第20个线程一来就满了,就继续向下执行了
package com.mashibing.juc.c_020;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class T07_TestCyclicBarrier {
public static void main(String[] args) {
//CyclicBarrier barrier = new CyclicBarrier(20);
CyclicBarrier barrier = new CyclicBarrier(20, () -> System.out.println(""));
/*CyclicBarrier barrier = new CyclicBarrier(20, new Runnable() {
@Override
public void run() {
System.out.println("ˣ");
}
});*/
for(int i=0; i<100; i++) {
new Thread(()->{
try {
barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}).start();
}
}
}
实际应用场景
限流(错误!!!):好多请求一下子打到数据库上,数据库容器宕机,这时要限流===>令牌桶
- 请求流量的入口特别多,但是后面的出口会被限制住(只有30个请求能过来),可以用CyclicBarrier
- 但是一般会用Guava RateLimiter(谷歌专门做的用于限流的服务类)
错误原因:限流的例子有点问题,因为少于20个就能直接过去,而不需要等着;正确的逻辑应该是超过20个的时候,超过20的部分等着,少于20的部分,直接过去
线程同步的时候:比如一个线程需要另外好多个线程的结果(执行结束)时,可以用CyclicBarrier
- 复杂操作:
-数据库 -网络 -文件 -1、2、3顺序执行,效率太低
- 并发执行
-不同的线程去执行不同的操作 -有的线程去数据库 -有的数据库去访问网络 -有的线程去访问文件