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

 

posted @ 2018-12-17 16:52  zlAdmin  阅读(355)  评论(0)    收藏  举报