【并发编程】- Phaser 使用awaitAdvanceInterruptibly方法异常中断机制

233 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第1天,点击查看活动详情

Phaser的awaitAdvanceInterruptibly(int.long,TimeUnit)方法

方法awaitAdvanceInterruptibly(int,long,TimeUnit)的作用是在指定的栏数等待最大的单位时间,如果在指定的时间内,栏数未变,则出现异常,否则继续向下运行。

实现代码如下:

public class ThreadA implements Runnable{

    private Phaser phaser;

    public ThreadA(Phaser phaser){
        super();
        this.phaser=phaser;
    }

    @Override
    public void run() {
        try {

            System.out.println(Thread.currentThread().getName()+" 第一个阶段开始时间:"+System.currentTimeMillis());
            phaser.awaitAdvanceInterruptibly(0,5, TimeUnit.SECONDS);
            System.out.println(Thread.currentThread().getName()+" 第一个阶段结束时间: "+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println("InterruptedException");
        } catch (TimeoutException e) {
            e.printStackTrace();
            System.out.println("TimeoutException");
        }
    }
}

运行代码如下:

public class PhaserAwaitAdvanceInterruptRun {
    public static void main(String[] args) {
            Phaser phaser = new Phaser(3);
            ThreadA threadA = new ThreadA(phaser);
            Thread thread = new Thread(threadA);
            thread.start();
    }
}

运行结果如下:

Thread-0 第一个阶段开始时间:1653548945840
java.util.concurrent.TimeoutException
	at java.util.concurrent.Phaser.awaitAdvanceInterruptibly(Phaser.java:800)
	at com.ozx.concurrentprogram.phaser.entity.ThreadA.run(ThreadA.java:39)
	at java.lang.Thread.run(Thread.java:748)
TimeoutException

从运行结果可看出,5秒之后phaser阶段值没有发生改变。

修改下运行类代码如下:

public class PhaserAwaitAdvanceInterruptRun {
    public static void main(String[] args) {
            Phaser phaser = new Phaser(3);
            ThreadA threadA = new ThreadA(phaser);
            Thread thread = new Thread(threadA);
            thread.start();
        try {
            Thread.sleep(1000);
            phaser.arrive();
            Thread.sleep(1000);
            phaser.arrive();
            System.out.println("时间:"+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果如下:

Thread-0 第一个阶段开始时间:1653550126385
时间:1653550128407
java.util.concurrent.TimeoutException
	at java.util.concurrent.Phaser.awaitAdvanceInterruptibly(Phaser.java:800)
	at com.ozx.concurrentprogram.phaser.entity.ThreadA.run(ThreadA.java:39)
	at java.lang.Thread.run(Thread.java:748)

从运行结果看出,5秒后phaser不满足栏数为3时,发生TimeoutException异常

修改运行类代码如下:

public class PhaserAwaitAdvanceInterruptRun {
    public static void main(String[] args) {
            Phaser phaser = new Phaser(3);
            ThreadA threadA = new ThreadA(phaser);
            Thread thread = new Thread(threadA);
            thread.start();
        try {
            Thread.sleep(1000);
            phaser.arrive();
            Thread.sleep(1000);
            phaser.arrive();
            System.out.println("时间:"+System.currentTimeMillis());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

运行结果如下:

Thread-0 第一个阶段开始时间:1653550284220
Thread-0 第一个阶段结束时间: 1653550286233
时间:1653550286233

修改运行类代码如下:

public class PhaserAwaitAdvanceInterruptRun {
    public static void main(String[] args) {
            Phaser phaser = new Phaser(3);
            ThreadA threadA = new ThreadA(phaser);
            Thread thread = new Thread(threadA);
            thread.start();
            thread.interrupt();
    }
}

运行结果如下:

Thread-0 第一个阶段开始时间:1653550409349
InterruptedException
java.lang.InterruptedException
	at java.util.concurrent.Phaser.awaitAdvanceInterruptibly(Phaser.java:798)
	at com.ozx.concurrentprogram.phaser.entity.ThreadA.run(ThreadA.java:39)
	at java.lang.Thread.run(Thread.java:748)

出现异常的原因是提前将还未到5秒的线程进行了中断。