JUC--CyclicBarrier
字面意思:循环障碍?
它要做的事情是,让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门,所有被屏障拦截的线程才会继续干活。
先直接上代码:
package com.zl.concurrency.example.aqs; import lombok.extern.slf4j.Slf4j; import java.util.concurrent.CyclicBarrier; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * CyclicBarrier测试类:让一组线程到达一个屏障(也可以叫同步点)时被阻塞,直到最后一个线程到达屏障时,屏障才会开门 * * @author zhagnlei * @ProjectName: zlAdmin * @create 2018-10-14 13:15 * @Version: 1.0 * <p>Copyright: Copyright (zl) 2018</p> **/ @Slf4j public class CyclicBarrierExample { private static CyclicBarrier barrier = new CyclicBarrier(5); public static void main(String[] args) throws InterruptedException { ExecutorService exectorService = Executors.newCachedThreadPool(); for (int i = 0; i < 10; i++) { final int threadNum = i; Thread.sleep(1000); exectorService.execute(() -> { try { race(threadNum); } catch (Exception e) { log.error("exception", e); } }); } exectorService.shutdown(); } private static void race(int threadNum) throws Exception { Thread.sleep(1000); log.info("{},is ready", threadNum); barrier.await(); log.info("{} continue"); } }
结果:
15:54:42.862 [pool-1-thread-1] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 0,is ready 15:54:43.855 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 1,is ready 15:54:44.856 [pool-1-thread-3] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 2,is ready 15:54:45.856 [pool-1-thread-4] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 3,is ready 15:54:46.856 [pool-1-thread-5] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 4,is ready15:54:46.857 [pool-1-thread-5] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:46.857 [pool-1-thread-4] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:46.857 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:46.857 [pool-1-thread-1] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:46.857 [pool-1-thread-3] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:47.857 [pool-1-thread-6] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 5,is ready 15:54:48.857 [pool-1-thread-4] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 6,is ready 15:54:49.858 [pool-1-thread-1] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 7,is ready 15:54:50.858 [pool-1-thread-3] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 8,is ready 15:54:51.859 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 9,is ready15:54:51.859 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:51.859 [pool-1-thread-4] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:51.859 [pool-1-thread-1] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:51.860 [pool-1-thread-3] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 15:54:51.859 [pool-1-thread-6] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue Process finished with exit code 0
分析:线程进入执行,调用barrier.await()方法,阻塞想吃,当阻塞线程数达到规定数后,唤醒全部阻塞线程;
这里的:CyclicBarrier的构造,处理可以传入指定阻塞线程数量外还可以指定一个匿名函数,即在唤醒全部线程之前之心的一个方法;比如将上述方法的中的private static CyclicBarrier barrier = new CyclicBarrier(5)换成
private static CyclicBarrier barrier = new CyclicBarrier(5,()->{
log.info("callback is running");
});
得到的结果如下:
16:50:12.579 [pool-1-thread-1] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 0,is ready 16:50:13.577 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 1,is ready 16:50:14.578 [pool-1-thread-3] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 2,is ready 16:50:15.578 [pool-1-thread-4] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 3,is ready 16:50:16.579 [pool-1-thread-5] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 4,is ready 16:50:16.579 [pool-1-thread-5] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - callback is running 16:50:16.580 [pool-1-thread-1] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:16.580 [pool-1-thread-4] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:16.580 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:16.580 [pool-1-thread-3] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:16.580 [pool-1-thread-5] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:17.579 [pool-1-thread-6] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 5,is ready 16:50:18.580 [pool-1-thread-5] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 6,is ready 16:50:19.580 [pool-1-thread-3] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 7,is ready 16:50:20.581 [pool-1-thread-4] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 8,is ready 16:50:21.581 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - 9,is ready 16:50:21.581 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - callback is running 16:50:21.581 [pool-1-thread-2] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:21.581 [pool-1-thread-6] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:21.581 [pool-1-thread-5] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:21.581 [pool-1-thread-3] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue 16:50:21.581 [pool-1-thread-4] INFO com.zl.concurrency.example.aqs.CyclicBarrierExample2 - {} continue Process finished with exit code 0
我们曾如此渴望生命的波澜,到后来才发现,人生最曼妙的风景是内心的淡定与从容