相位终止后的java.util.concurrent.Phaser回调

时间:2017-01-27 12:40:17

标签: java concurrency synchronization phaser

我从WITH machinery(hhmachineryid,hhid,machineryid) AS ( SELECT 1,'10-10-009-0001',7 UNION ALL SELECT 1,'10-07-005-0001',7 UNION ALL SELECT 2,'10-02-054-0001',3 ) , household(hhid,hh_comm_code) AS ( SELECT '10-01-001-0001','10-01-001' UNION ALL SELECT '10-01-001-0002','10-01-001' ) , community(communitycode,community) AS ( SELECT '10-01-001','sekondi' ) SELECT community , communitycode , COUNT(*) AS household_count FROM community c JOIN household h ON c.communitycode = h.hh_comm_code JOIN machinery m ON h.hhid = m.hhid WHERE c.community='sekondi' AND m.machineryid=1 GROUP BY community , communitycode ; 包中调查Phaser并编写了代码示例:

java.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 X 严格打印

我理解为什么我的代码工作正常但我不知道如何实现所需的行为。我认为这是可能的,因为在所有地方都写了PhaseThread # start execute phase X+1涵盖Phaser功能。

1 个答案:

答案 0 :(得分:2)

阅读Phaser的Java文档会显示一个名为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();
        }
    }
}