话说北京有个地儿叫大栅栏,在前门前,天桥下,过了天桥就到了天坛。这个大栅栏标准读音是da zha lan
,但如果你非得这么念可能要遭到本地人笑话的,正确的土话读法是:da she lan er
。
言归正传,今天讲到的工具叫CyclicBarrier,直译过来就叫做栅栏。
栅栏其实就是口袋,玉米装满口袋就需要扎口。下面通过一个扎口袋的例子初步认识一下CyclicBarrier:
public class CyclicBarrierDemo {
final static CyclicBarrier BARRIER = new CyclicBarrier(10,()->{
System.out.println("扎口袋");
});
static class Maize implements Runnable{
final static AtomicInteger incr = new AtomicInteger();
@Override
public void run() {
try {
System.out.println("装"+incr.getAndIncrement()+"号玉米进口袋");
Thread.sleep(new Random().nextInt(10)*100);
BARRIER.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(10);
for (int i = 0; i < 10; i++) {
executorService.execute(new Maize());
}
executorService.shutdown();
}
}
CyclicBarrier的工作流程是:一个人(线程)向口袋装一个玉米后,进行等待(await),直到有10个人分别装了玉米,再通知另一个人(老大)进行扎口袋。
这里的老大定义在CyclicBarrier的构造函数的第二个参数上。
诶,我们发现这个CyclicBarrier怎么跟CountDownLatch那么像呢?除了他没有countDown()方法,好像用法是一样的呢?
别着急,细细查看,他和CountDownLatch还是有比较大的区别的:
- CountDownLatch.countDown()之后不用阻塞,只是倒计时了一下。而CyclicBarrier是大家必须等待一个时刻,然后呼唤出老大
- CountDownLatch并没有呼唤老大这个机制
所以还是要区别一下他们两个的用法的,简单来说,倒计时第一个想起的是CountDownLatch;而需要扎口袋或设栅栏则用CyclicBarrier。