并发工具 CyclicBarrier

定义

CyclicBarrier:Cyclic(循环),Barrier(屏障)。循环屏障或者循环栅栏,它的功能就是,让一组线程到达一个屏障时被阻塞,直到最后一个线程到达屏障时,屏障才会打开,此时被阻塞的线程就会继续执行。当线程调用CyclicBarrier的await()方法后,相当于告诉CyclicBarrier我到达了屏障,然后当前线程就会被阻塞。

应用场景

CyclicBarrier可以用于多个线程计算结果,最后合并计算结果的场景。

代码清单

CyclicBarrier的定义为3,即当有3个线程到达屏障时,就会打开屏障,让这三个线程继续往下执行。

package com.mark.learning.concurrent2.flowcontrol.cyclicbarrier;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CyclicBarrierDemo1 {

    /** 定义CyclicBarrier,屏障大小为3 **/
    private static final CyclicBarrier cyclicBarrier = new CyclicBarrier(3, new Runnable() {
        @Override
        public void run() {
            System.out.println("所有线程都到齐了,统一出发");
        }
    });


    public static void main(String[] args) {
        //声明一个固定大小的线程池,线程容量为5
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        //执行10个子任务
        for (int i = 0; i < 10; i++) {
            executorService.execute(new Task(cyclicBarrier));
        }
        executorService.shutdown();
    }

    private static class Task implements Runnable {

        private CyclicBarrier cyclicBarrier;

        private Task(CyclicBarrier cyclicBarrier) {
            this.cyclicBarrier = cyclicBarrier;
        }

        @Override
        public void run() {
            try {
                Thread.sleep(1000);
                System.out.println(Thread.currentThread().getName() + "到达了集合地点,正在等待其他线程");
                cyclicBarrier.await();
                System.out.println(Thread.currentThread().getName() + "出发!");
            } catch (InterruptedException | BrokenBarrierException e) {

                e.printStackTrace();
            }

        }
    }
}

运行结果
实例中屏障的大小为3,任务数量为10。3个任务为一组依次通过屏障,那么最后有一个任务被阻塞住,因为没有多余的两个线程到达屏障了。

CyclicBarrier和CountDownLath的区别

  • 作用不用:CyclicBarrier需要等待一定数量的线程到达屏障后,这些线程才能继续执行,显而易见CyclicBarrier面向的是线程。CountDownLath是等待计数为0时,而计数减一这个操作不定义是有由一个线程执行了,可以在一个线程中进行多次减一,CountDownLath面向的事件。
  • 可重用性不同:CountDownLath在倒数到0时,门闩打开后就不能再次使用了。而CyclicBarrier可以复用。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章