【并发编程】- Phaser 消耗parties值两种方式

617 阅读2分钟

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

Phaser的getArrivedParties()和getUnarrivedParties()方法测试

方法getArrivedParties()获得已经被使用的parties个数

方法getUnarrivedParties()获得未被使用的parties个数

线程执行代码如下:

public class ThirdThread implements Runnable {
    private Phaser phaser;

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

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+" 第一阶段开始时间: "+System.currentTimeMillis());
        phaser.arriveAndAwaitAdvance();
        System.out.println(Thread.currentThread().getName()+" 第一阶段结束时间:  "+System.currentTimeMillis());
    }
}

运行类执行代码如下:

public class PhaserPartiesRun {
    public static void main(String[] args) throws InterruptedException {
        Phaser phaser = new Phaser(7);
        ThirdThread[] thirdThreads = new ThirdThread[5];
        for (int i = 0; i <thirdThreads.length ; i++) {
            thirdThreads[i]=new ThirdThread(phaser);
            Thread thread = new Thread(thirdThreads[i]);
            thread.setName("Thread - "+(i+1));
            thread.start();
        }
        Thread.sleep(5000);
        System.out.println("已到达:"+phaser.getArrivedParties());
        System.out.println("未到达:"+phaser.getUnarrivedParties());
    }
}

运行结果如下:

Thread - 2 第一阶段开始时间: 1650855919453
Thread - 3 第一阶段开始时间: 1650855919455
Thread - 1 第一阶段开始时间: 1650855919453
Thread - 4 第一阶段开始时间: 1650855919460
Thread - 5 第一阶段开始时间: 1650855919461
已到达:5
未到达:2

Phaser的arrive()方法

方法arrive()的作用是使parties值加1,并且不在屏障处等待,直接接着往下运行,并且Phaser类有计数重置功能。

运行类代码如下:

public class PhaserArriveRun {
    public static void main(String[] args) {
        Phaser phaser = new Phaser(2) {
            protected boolean onAdvance(int phase, int registeredParties) {
                System.out.println("到达了未通过!phase=" + phase + " registerParties=" + registeredParties);
                return super.onAdvance(phase, registeredParties);
            }
        };

        System.out.println("第一阶段 getPhase="+phaser.getPhase()+"getRegisteredParties="+phaser.getRegisteredParties()+" getArrivedParties="+phaser.getArrivedParties());
        phaser.arrive();
        System.out.println("第一阶段 getPhase="+phaser.getPhase()+"getRegisteredParties="+phaser.getRegisteredParties()+" getArrivedParties="+phaser.getArrivedParties());

        System.out.println("第二阶段 getPhase="+phaser.getPhase()+"getRegisteredParties="+phaser.getRegisteredParties()+" getArrivedParties="+phaser.getArrivedParties());
        phaser.arrive();
        System.out.println("第二阶段 getPhase="+phaser.getPhase()+"getRegisteredParties="+phaser.getRegisteredParties()+" getArrivedParties="+phaser.getArrivedParties());

        System.out.println("第三阶段 getPhase="+phaser.getPhase()+"getRegisteredParties="+phaser.getRegisteredParties()+" getArrivedParties="+phaser.getArrivedParties());
        phaser.arrive();
        System.out.println("第三阶段 getPhase="+phaser.getPhase()+"getRegisteredParties="+phaser.getRegisteredParties()+" getArrivedParties="+phaser.getArrivedParties());

    }
}

运行结果如下:

第一阶段 getPhase=0getRegisteredParties=2 getArrivedParties=0
第一阶段 getPhase=0getRegisteredParties=2 getArrivedParties=1
第二阶段 getPhase=0getRegisteredParties=2 getArrivedParties=1
到达了未通过!phase=0 registerParties=2
第二阶段 getPhase=1getRegisteredParties=2 getArrivedParties=0
第三阶段 getPhase=1getRegisteredParties=2 getArrivedParties=0
第三阶段 getPhase=1getRegisteredParties=2 getArrivedParties=1

​ 从运行结果可看出,方法arrive()的功能是使getArrivedParties()计数加1,不等待其他线程到达屏障。

​ 在控制台中多次出现getArrivedParties=0的运行结果,所以可分析出Phaser类在经过屏障点后计数能被重置。