0

Phaserjava.util.concurrent包中调查并编写了代码示例:

public class ThreadsApp {

    public static void main(String[] args) {

        Phaser phaser = new Phaser(1);
        new Thread(new PhaseThread(phaser, "PhaseThread 1")).start();
        new Thread(new PhaseThread(phaser, "PhaseThread 2")).start();

        // ждем завершения фазы 0
        int phase = phaser.getPhase();
        phaser.arriveAndAwaitAdvance();
        System.out.println("phase " + phase + " finished");
        // ждем завершения фазы 1
        phase = phaser.getPhase();
        phaser.arriveAndAwaitAdvance();
        System.out.println("phase " + phase + " finished");

        // ждем завершения фазы 2
        phase = phaser.getPhase();
        phaser.arriveAndAwaitAdvance();
        System.out.println("phase " + phase + " finished");

        phaser.arriveAndDeregister();
    }
}

class PhaseThread implements Runnable {

    Phaser phaser;
    String name;

    PhaseThread(Phaser p, String n) {

        this.phaser = p;
        this.name = n;
        phaser.register();
    }

    public void run() {
        try {
            System.out.println(name + " start execute phase " + phaser.getPhase());
            Thread.sleep(1000);
            phaser.arriveAndAwaitAdvance(); // сообщаем, что первая фаза достигнута

            System.out.println(name + " start execute phase " + phaser.getPhase());
            Thread.sleep(2000);
            phaser.arriveAndAwaitAdvance(); // сообщаем, что вторая фаза достигнута

            System.out.println(name + " start execute phase " + phaser.getPhase());
            Thread.sleep(3000);
            phaser.arriveAndDeregister(); // сообщаем о завершении фаз и удаляем с регистрации объекты

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

输出:

PhaseThread 2 start execute phase 0
PhaseThread 1 start execute phase 0
PhaseThread 2 start execute phase 1
phase 0 finished
PhaseThread 1 start execute phase 1
phase 1 finished
PhaseThread 1 start execute phase 2
PhaseThread 2 start execute phase 2
phase 2 finished

输出与我想要的有点不同:

我想 :

PhaseThread 2 start execute phase 0
PhaseThread 1 start execute phase 0
phase 0 finished
PhaseThread 2 start execute phase 1
PhaseThread 1 start execute phase 1
phase 1 finished
PhaseThread 1 start execute phase 2
PhaseThread 2 start execute phase 2
phase 2 finished

因此,我希望两者 之后和之前都严格phase X finished打印PhaseThread # start execute phase XPhaseThread # start execute phase X+1

我理解为什么我的代码工作不正常,但我不知道如何实现所需的行为。我认为这是可能的,因为到处都写了Phaser覆盖CyclicBarrier功能。

4

1 回答 1

2

阅读Phaser的 Java Doc显示了一个调用的覆盖方法onAdvance,该方法可用于打印phase X finished阶段实际完成的时间。只需修改代码如下。

public class ThreadsApp {

    public static void main(String[] args) {

        Phaser phaser = new Phaser(1) {
            protected boolean onAdvance(int phase, int parties) { 
                System.out.println("phase " + phase + " finished");
                return false; 
            }
        };
        new Thread(new PhaseThread(phaser, "PhaseThread 1")).start();
        new Thread(new PhaseThread(phaser, "PhaseThread 2")).start();

        // ждем завершения фазы 0
        int phase = phaser.getPhase();
        phaser.arriveAndAwaitAdvance();

        // ждем завершения фазы 1
        phase = phaser.getPhase();
        phaser.arriveAndAwaitAdvance();


        // ждем завершения фазы 2
        phase = phaser.getPhase();
        phaser.arriveAndDeregister();
    }
}

class PhaseThread implements Runnable {

    Phaser phaser;
    String name;

    PhaseThread(Phaser p, String n) {

        this.phaser = p;
        this.name = n;
        phaser.register();
    }

    public void run() {
        try {
            System.out.println(name + " start execute phase " + phaser.getPhase());
            Thread.sleep(1000);
            phaser.arriveAndAwaitAdvance(); // сообщаем, что первая фаза достигнута

            System.out.println(name + " start execute phase " + phaser.getPhase());
            Thread.sleep(2000);
            phaser.arriveAndAwaitAdvance(); // сообщаем, что вторая фаза достигнута

            System.out.println(name + " start execute phase " + phaser.getPhase());
            Thread.sleep(3000);
            phaser.arriveAndDeregister(); // сообщаем о завершении фаз и удаляем с регистрации объекты

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
于 2017-01-27T13:52:31.920 回答