【并发编程】- Phaser使用onAdvance启动或禁用屏障

162 阅读3分钟

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

方法onAdvance()的使用

实现代码如下:

public class PhaserAdvanceService {
    private Phaser phaser;

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

    public void startMethod(){
            try {
                System.out.println("第一次开始线程名:"+Thread.currentThread().getName()+"  时间: "+System.currentTimeMillis());
                if(Thread.currentThread().getName().equals("Thread-1")){
                Thread.sleep(5000);
                }
                phaser.arriveAndAwaitAdvance();
                System.out.println("第一次结束线程名:"+Thread.currentThread().getName()+"  结束 phaser的值:"+phaser.getPhase()+" 时间: "+System.currentTimeMillis());

                System.out.println("第二次开始线程名:"+Thread.currentThread().getName()+"  时间: "+System.currentTimeMillis());
                if(Thread.currentThread().getName().equals("Thread-1")){
                    Thread.sleep(5000);
                }
                phaser.arriveAndAwaitAdvance();
                System.out.println("第二次结束线程名:"+Thread.currentThread().getName()+"  结束 phaser的值:"+phaser.getPhase()+" 时间: "+System.currentTimeMillis());

                System.out.println("第三次开始线程名:"+Thread.currentThread().getName()+"  时间: "+System.currentTimeMillis());
                if(Thread.currentThread().getName().equals("Thread-1")){
                    Thread.sleep(5000);
                }
                phaser.arriveAndAwaitAdvance();
                System.out.println("第三次结束线程名:"+Thread.currentThread().getName()+"  结束 phaser的值:"+phaser.getPhase()+" 时间: "+System.currentTimeMillis());

            } catch (InterruptedException e) {
                e.printStackTrace();

        }
    }
}

线程执行代码如下:

public class ThreadA implements Runnable{

    private PhaserAdvanceService service;

    public ThreadA(PhaserAdvanceService service){
        super();
        this.service=service;
    }

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

    private PhaserAdvanceService service;

    public ThreadB(PhaserAdvanceService service){
        super();
        this.service=service;
    }

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

运行类代码如下:

public class PhaserAdvanceRun {
    public static void main(String[] args) {
        Phaser phaser = new Phaser(2){
            protected boolean onAdvance(int phase, int registeredParties) {
                System.out.println("protected boolean onAdvance(int phase,int registeredParties) 被调用!");
                //返回true不等待了,phaser呈无效/销毁的状态
                //false则Phaser继续工作
                return true;
            }
        };
        PhaserAdvanceService service = new PhaserAdvanceService(phaser);
        ThreadA threadA = new ThreadA(service);
        new Thread(threadA).start();

        ThreadB threadB = new ThreadB(service);
        new Thread(threadB).start();

    }
}

运行结果如下:

第一次开始线程名:Thread-0  时间: 1650785467493
第一次开始线程名:Thread-1  时间: 1650785467497
protected boolean onAdvance(int phase,int registeredParties) 被调用!
第一次结束线程名:Thread-0  结束 phaser的值:-2147483647 时间: 1650785472502
第二次开始线程名:Thread-0  时间: 1650785472503
第一次结束线程名:Thread-1  结束 phaser的值:-2147483647 时间: 1650785472502
第二次开始线程名:Thread-1  时间: 1650785472504
第二次结束线程名:Thread-0  结束 phaser的值:-2147483647 时间: 1650785472503
第三次开始线程名:Thread-0  时间: 1650785472504
第三次结束线程名:Thread-0  结束 phaser的值:-2147483647 时间: 1650785472504
第二次结束线程名:Thread-1  结束 phaser的值:-2147483647 时间: 1650785477516
第三次开始线程名:Thread-1  时间: 1650785477517
第三次结束线程名:Thread-1  结束 phaser的值:-2147483647 时间: 1650785482520

从运行结果来看,线程Thread-0只等待1次5秒,而在其他的屏障处并未等待,都是快速打印,线程Thread-0不再发生阻塞,这就是onAdvance返回true的效果,取消屏障。