Java多线程同步屏障CyclicBarrierDemo对象

情到浓时终转凉″ 提交于 2020-03-16 18:05:58

一、概述

同步屏障可以使多条线程彼此等待,直到抵达某个公共的屏障点。线程之间彼此等待时已经抵达公共屏障点的线程不会继续往下执行,会在所有线程抵达公共屏障点之前一直阻塞。CyclicBarrierDemo对象可以重用,这点与上一篇中的CountDownLatch对象不同,CountDowLatch时不可重用的。

二、主要方法

CyclicBarrier(int parties):初始化一个包含指定parties数目的CyclicBarrier对象

int await() throws InterruptedException, BrokenBarrierException:强制阻塞线程,一直等待所有的parties线程都在同步屏障上调用了await()方法

int await(long time, DateUtil util):指定线程的等待时间,如果超时会抛出异常 

void reset():重置对象,如果此时有线程在这个对象上阻塞,则会抛出异常

int getNumberWaiting(): 返回阻塞的线程数量。

三、代码示例

高速公路的建造:高速公路的建造不是从头到尾建造的,高速公路在规划后之后,会将规划路线分段施工,一般情况下一条完整的高速公路在施工时是好几段同时施工的。下面我们使用CyclicBarrierDemo对象来实现建造一条完整高速公路的场景。

如上图中所示,假如上面三段是一条完成的高速公路,现在分三段施工,每一段完成就是抵达了公共屏障点。

package com.scott.current;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.BrokenBarrierException;

/**
 * 一个CyclicBarrier的简单例子
 *
 * 模拟高速公路建造:高速公路的建造是分段进行的,会将之前规划好的高速公路分割为 N 段
 * 然后可能是 M 段一起施工,当 N 段全部完成后即代表该调高速公路建造完成
 * @author Scott
 */
public class CyclicBarrierDemo {

    /** 假设高速公路被分割为 3 段 */
    private final static int N = 3;

    public static void main(String[] args) {
        String[] roadNameArray = new String[]{"广梧高速", "广昆高速", "广湛高速"};
        // 构建指定执行共同目标线程数量的同步屏障对象
        CyclicBarrier barrier  = new CyclicBarrier(N);
        // N 段高速公路同时开工建造
        for(int i = 0; i < roadNameArray.length; i++) {
            new BuildRoad(barrier, roadNameArray[i]).start();
        }
    }

    /**
     * 建造一段高速公路
     */
    static class BuildRoad extends Thread{
        // 同步屏障
        private CyclicBarrier cyclicBarrier;
        private BuildRoad(CyclicBarrier cyclicBarrier, String name) {
            this.cyclicBarrier = cyclicBarrier;
            setName(name);
        }
        @Override
        public void run() {
            System.out.println("线程:" + Thread.currentThread().getName() + "正在建造中...");
            try {
                // 睡眠来模拟每段的建造
                Thread.sleep(5000);
                System.out.println("线程"+Thread.currentThread().getName()+"建造完成。");
                cyclicBarrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
            System.out.println("所有段的高速公路建造完成,准备通车!!!");
        }
    }
}

执行结果:

按照这个场景,上述代码中一共是三条线程,每条线程执行到 await() 方法就是抵达了公共屏障点,也就是场景中的其中一段高速公共施工完成了。从结果里面可以看到,没有全部抵达公共屏障点之前,抵达了的线程都是处于阻塞状态的。

这里面涉及到多条线程和一个共享变量(CyclicBarrier barrier)

上述就是关于CyclicBarrier对象的简单使用。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!