什么时候使用CyclicBarrier

版权声明:未经允许禁止转载 https://blog.csdn.net/weixin_38481963/article/details/88070679

CyclicBarrier适用于这样的情况:你希望创建一组任务,他们并行的执行工作,然后在进行下一个步骤之前等待,直到所有的任务都完成。这非常像CountDownLatch,只是CountDownLatch是只触发一次的事件,而CyclicBarrier可以多次重用。

CyclicBarrier用途有两个:

  1. 让一组线程等待至某个状态后再同时执行。
  2. 让一组线程等待至某个状态后,执行指定的任务。

这两个特点对应着CyclicBarrier的两个构造函数。

//第一个构造函数
public CyclicBarrier(int parties) {...}

//第二个构造函数
public CyclicBarrier(int parties, Runnable barrierAction) {...}

之后针对这两个特性,分别编写样例测试。

1、让一组线程等待至某个状态后再同时执行

例如:小明、小刚和小华约定好了,放学后在校门口集合,一起回家。

用CyclicBarrier模拟就是:


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

class GoHome implements Runnable{
    private String name;
    private final CyclicBarrier barrier;
    public GoHome(String name, CyclicBarrier barrier){
        this.name = name;
        this.barrier = barrier;
    }
    public void run(){
        try{
            System.out.println(name + "出发");
            TimeUnit.MILLISECONDS.sleep(500);  //模拟每个人到达学校门口的时间
            System.out.println(name + "到达学校门口");
            barrier.await();
            System.out.println("所有人到齐,一起回家");
        }catch(InterruptedException e){
            e.printStackTrace();
        }catch(BrokenBarrierException e){
            e.printStackTrace();
        }
    }
}

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3);
        String names[] = {"小明","小刚","小华"};
        ExecutorService exe = Executors.newCachedThreadPool();
        for(int i=0; i< names.length; i++)
        {
            exe.execute(new GoHome(names[i],barrier));
        }
        exe.shutdown();
    }
}


结果:

小明出发
小刚出发
小华出发
小刚到达学校门口
小明到达学校门口
小华到达学校门口
所有人到齐,一起回家
所有人到齐,一起回家
所有人到齐,一起回家

你还可以尝试注释掉barrier.await();,看一下结果如何。

CyclicBarrie是可以重用的:
你可以在Main函数中追加,以下代码,了解CyclicBarrie的复用特性:

		try{
            TimeUnit.MILLISECONDS.sleep(2000);
        }catch(InterruptedException e){
            e.printStackTrace();
        }

        //又来了三个人
        String others[] = {"Tom","Jerry","Marry"};
        for(int i=0; i<3; i++)
        {
            new Thread(new GoHome(others[i],barrier)).start();
        }

2、让一组线程等待至某个状态后,执行指定的任务。

这里要注意的是,驱动指定任务的线程,是利用上面的线程中一个来执行的,并没有启动新的线程。

我们改一下上面那个场景:小明、小刚和小华约定好了,放学后在餐厅门口集合,一起去吃饭。


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

class GoHome implements Runnable{
    private String name;
    private final CyclicBarrier barrier;
    public GoHome(String name, CyclicBarrier barrier){
        this.name = name;
        this.barrier = barrier;
    }
    public void run(){
        try{
            System.out.println(Thread.currentThread().getName() + " : " + name + "出发");
            TimeUnit.MILLISECONDS.sleep(500);  //模拟每个人到达学校门口的时间
            System.out.println(Thread.currentThread().getName() + " : " + name + "到达餐厅门口");
            barrier.await();
        }catch(InterruptedException e){
            e.printStackTrace();
        }catch(BrokenBarrierException e){
            e.printStackTrace();
        }
    }
}

class EatLunch implements Runnable{
    public void run(){
        System.out.println(Thread.currentThread().getName() + " : " + "大家一起去打饭");
    }
}

public class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3,new EatLunch());
        String names[] = {"小明","小刚","小华"};
        ExecutorService exe = Executors.newCachedThreadPool();
        for(int i=0; i< names.length; i++)
        {
            exe.execute(new GoHome(names[i],barrier));
        }
        exe.shutdown();

    }
}

结果:

pool-1-thread-1 : 小明出发
pool-1-thread-2 : 小刚出发
pool-1-thread-3 : 小华出发
pool-1-thread-1 : 小明到达餐厅门口
pool-1-thread-2 : 小刚到达餐厅门口
pool-1-thread-3 : 小华到达餐厅门口
pool-1-thread-3 : 大家一起去打饭

猜你喜欢

转载自blog.csdn.net/weixin_38481963/article/details/88070679