天天看点

CyclicBarrier循环栅栏

@[toc]

CyclicBarrier循环栅栏

  • CyclicBarrier循环栅栏和CountDownLatch 很类似 ,都能阻塞一组线程
  • 当有大量线程相互配合,分别计算不同任务,并且需要最后统一汇总的时候,我们可以使用CyclicBarrier 。CyclicBarrier可以构造一个集结点,当某一个线程执行完毕,他就会到集结点等待,知道所有线程都到了集结点,那么该栅栏就被撤销,所以有线程在统一出发,继续执行剩下都任务。
  • 生活中的例子:“ 咋们3个人明天中午在学校碰面,都到齐后,一起讨论下学期的计划”

代码演示

package com.yxl.task;

import lombok.SneakyThrows;

import java.util.concurrent.CyclicBarrier;

/**
 * 演示CyclicBarrier demo
 */
public class CyclicBarrierDemo {

    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() {
            @Override
            public void run() {
                System.out.println("所有人到了,大家一起出发");
            }
        });
        for (int i = 0; i < 5; i++) {
            new Thread(new Task(i,cyclicBarrier)).start();
        }
    }


    static class  Task implements Runnable{
        private int id;

        private CyclicBarrier cyclicBarrier;

        public Task(int id, CyclicBarrier cyclicBarrier) {
            this.id = id;
            this.cyclicBarrier = cyclicBarrier;
        }

        @SneakyThrows
        @Override
        public void run() {
            System.out.println("线程"+id + "前往集合地点");
            Thread.sleep((long) (Math.random()*10000));
            System.out.println("线程"+id+"到了集合地点,等待其他人到达");
            cyclicBarrier.await();
            System.out.println("线程"+id+"出发了");
        }
    }
}
           

执行结果

CyclicBarrier循环栅栏

并且 CyclicBarrier 有个特点 可重用

for (int i = 0; i < 10; i++) {
            new Thread(new Task(i,cyclicBarrier)).start();
        }           

我们把这个改成10个线程,查看结果

CyclicBarrier循环栅栏

一起出发,5个先到 5个先走 ,可重用的特性

CyclicBarrier 和 CountDownLatch 的区别

  • 作用不同 CyclicBarrier要等固定数量等线程都达到了栅栏位置才能继续执行,而CountDownLatch 只需等待数字到0,也就是说,CountDownLatch 用于事件,但是CyclicBarrier 是用于线程的
  • 可用性不同:CountDownLatch在倒数到0并处罚门阀打开后,就不能再次使用了,除非新建新到实例;而CyclicBarrier可以重复使用
  • 个人博客地址: http://blog.yanxiaolong.cn/

继续阅读