【并发编程】- CyclicBarrier await超时异常

343 阅读1分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情

CyclicBarrier 方法await(long timeout,TimeUnit unit)超时出现异常

实现代码如下:

public class CyclicBarrierAwaitTimeService {
    public CyclicBarrier cyclicBarrier=new CyclicBarrier(3, new Runnable() {
        @Override
        public void run() {
            System.out.println("彻底结束了 "+System.currentTimeMillis());
        }
    });

    public void startMethod(){
        try {
        System.out.println(Thread.currentThread().getName()+" 准备!"+System.currentTimeMillis());
        if(Thread.currentThread().getName().equals("Thread-0")){
            System.out.println("Thread-0 执行了cyclicBarrier.await(5,TimeUnit.SECONDS)");
            cyclicBarrier.await(5,TimeUnit.SECONDS);
        }
        if(Thread.currentThread().getName().equals("Thread-1")){
            System.out.println("Thread-1 执行了cyclicBarrier.await()");
            cyclicBarrier.await();
        }
            System.out.println(Thread.currentThread().getName()+" 开始!"+System.currentTimeMillis());
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName()+" 进入catch(InterruptedException e)");
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            System.out.println(Thread.currentThread().getName()+" 进入catch(BrokenBarrierException e)");
            e.printStackTrace();
        } catch (TimeoutException e) {
            System.out.println(Thread.currentThread().getName()+" 进入catch(TimeoutException e)");
            e.printStackTrace();
        }
    }
}

创建两个线程执行代码如下:

public class FirstThread implements Runnable{
    private CyclicBarrierAwaitTimeService service;

    public FirstThread(CyclicBarrierAwaitTimeService service){
        super();
        this.service=service;
    }

    @Override
    public void run() {
        service.startMethod();
    }
}
public class SecondThread implements Runnable {
    private CyclicBarrierAwaitTimeService service;

    public SecondThread(CyclicBarrierAwaitTimeService service){
        super();
        this.service=service;
    }

    @Override
    public void run() {
        service.startMethod();
    }
}

运行类代码如下:

public class CyclicBarrierAwaitTimeRun {
    public static void main(String[] args) {
        CyclicBarrierAwaitTimeService service = new CyclicBarrierAwaitTimeService();
        FirstThread firstThread = new FirstThread(service);
        new Thread(firstThread).start();
        SecondThread secondThread = new SecondThread(service);
        new Thread(secondThread).start();
    }
}

运行结果如下:

Thread-0 准备!1650511435578
Thread-0 执行了cyclicBarrier.await(5,TimeUnit.SECONDS)
Thread-1 准备!1650511435594
Thread-1 执行了cyclicBarrier.await()
Thread-1 进入catch(BrokenBarrierException e)
Thread-0 进入catch(TimeoutException e)
java.util.concurrent.BrokenBarrierException
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:250)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:362)
	at com.ozx.concurrentprogram.cyclicBarrier.service.CyclicBarrierAwaitTimeService.startMethod(CyclicBarrierAwaitTimeService.java:30)
	at com.ozx.concurrentprogram.cyclicBarrier.entity.SecondThread.run(SecondThread.java:20)
	at java.lang.Thread.run(Thread.java:748)
java.util.concurrent.TimeoutException
	at java.util.concurrent.CyclicBarrier.dowait(CyclicBarrier.java:257)
	at java.util.concurrent.CyclicBarrier.await(CyclicBarrier.java:435)
	at com.ozx.concurrentprogram.cyclicBarrier.service.CyclicBarrierAwaitTimeService.startMethod(CyclicBarrierAwaitTimeService.java:26)
	at com.ozx.concurrentprogram.cyclicBarrier.entity.FirstThread.run(FirstThread.java:20)
	at java.lang.Thread.run(Thread.java:748)

从运行结果可看出,方法await(long timeout,TimeUnit unit)的功能是如果在指定时间内达到parties的数量,则程序继续向下运行,否则如果出现超时,则抛出TimeoutException异常。