多线程-并发:介绍CyclicBarrier

承接上一篇。多线程-并发:介绍CountDownLatch

本文依然以《天龙八部》四大恶人举例。

纵览整本小说,四大恶人为了准备杀段正淳集结在大理,为了歼灭丐帮集结在杏子林,为了少室山大战集结在少室山....

我们发现,四大恶人仅仅一次集合是不够的!也就是说,这“四个线程”仅仅并发协作一次不够的!

但是CountDownLatch却是一次性的并发工具。由此,CyclicBarrier有了勇武之地。

/*
CyclicBarrier循环屏障
用途:协同指定数目的线程,让这些线程在这个屏障前等待,知道所有线程都到达了这个屏障,在一起继续执行。线程继续执行后,这个屏障可再次使用,因此为循环屏障。
*/
public class CyclicBarrier {
    //构造方法
    //parties:制定多有少个部分(线程)参与,被称为参与数。
    public CyclicBarrier(int parties){...}

    //构造方法
    /*
        barrierAction:所有参与者都达到屏障时执行的一次的命令,在一组线程中的最后一个线程达到之后(但在释放所有线程之前),在该线程中执行该命令,该命令只在每个屏障点运行一次。若要在继续执行所有参与线程之前更新共享状态,此屏障操作很有用!
    */
    public CyclicBarrier(int parties , Runnable barrierAction){...}

    //等待方法
    /*
        线程执行过程中调用await()方法,表明自己已达到屏障,自己阻塞,等待其他线程到达屏障;所有参与线程都到达屏障,即等待线程数==参与者,则释放所有线程,让他们继续执行。
        返回int值是到达的当前线程的索引号,注意索引号是从parties-1开始递减到0。
        BrokenBarrierExcepyion:屏障被破坏异常,当调用await时,或等待过程中屏障被破坏,则会抛出该异常。
    */
    public int await() throws InterruptedException, BrokenBarrierException {...}

    //以下方法不做重点讨论

    //等待指定时长,如到了时间还不能释放,则将抛出TimeoutException
    public int await(long timeout, TimeUnit unit)
        throws InterruptedException,
               BrokenBarrierException,
               TimeoutException {...}

    //获取当前等在屏障处的线程数
    public int getNumberWaiting() {}

    //判断线程是否被破坏
    public boolean isBroken() {}    

    //重置屏障为初始状态。如果当前有线程正在等待,则这些线程将被释放并抛出BrokenBarrierException
      public void reset() {}

}

CyclicBarrier使用注意事项:

一定要保证有足够的参与者线程,否则会一直被阻塞在屏障处。

在线程池中使用要更加小心!确保池的线程数>=要求的参与数

CyclicBarrier适用场景:

等待一起出发。

多次等待一起出发。

        CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
		for(int i = 0 ; i < 4 ; i++) {
			new Thread((i + 1) + ""){
				@Override
				public void run() {
					System.out.println("大理城天下第" + this.getName() + "大恶人到了");
					cyclicBarrier.await();
					System.out.println("杏子林天下第" + this.getName() + "大恶人到了");
					cyclicBarrier.await();
					System.out.println("少室山天下第" + this.getName() + "大恶人到了");
				}
			}.start();
		}

注:为了美观await()方法没有加try-catch

 

CyclicBarrier和CountDownLatch的区别:

CountDownLatch:是一部分线程等待另一部分线程来唤醒。

CyclicBarrier:是参与线程彼此等待,都到达了,在一起继续。

CountDownLatch不可循环使用,都到达了,在一起继续。

猜你喜欢

转载自blog.csdn.net/MonkeyDCoding/article/details/81284162
今日推荐