天天看點

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/

繼續閱讀