0

给定一个具有初始化 Phaser 的 main 方法的类,并创建(比如说)3 个线程来计算同一个 Phaser 上的阶段。

public class PhaserDemo2 implements Runnable {

    private static Phaser CLASS_PHASER;
    private static int COUNTER;

    public static void main(String[] args) {
        COUNTER = 5;
        // create a Phaser and register main Thread
        CLASS_PHASER = new Phaser(1);
        System.out.println(Integer.MIN_VALUE);
        System.out.println("Phase value:" + CLASS_PHASER.getPhase() + ", Registered Parties:" 
                + CLASS_PHASER.getRegisteredParties() + ", and Counter:" + COUNTER);
        // create 3 Threads
        new Thread(new PhaserDemo2()).start();
        new Thread(new PhaserDemo2()).start();
        new Thread(new PhaserDemo2()).start();
        // de-register main Thread
        CLASS_PHASER.arriveAndDeregister();
    }

    @Override
    public void run() {
        // register the current Thread with Phaser
        CLASS_PHASER.register();
        // print details
        System.out.println("Phase value:" + CLASS_PHASER.getPhase() + ", Registered Parties:" 
                + CLASS_PHASER.getRegisteredParties() + ", and Counter:" + COUNTER);
        // wait till other Threads have printed as well
        CLASS_PHASER.arriveAndAwaitAdvance();
        // de-register this Thread
        CLASS_PHASER.arriveAndDeregister();
    }
}

该代码适用于大多数执行,并产生如下输出,

-2147483648
Phase value:0, Registered Parties:1, and Counter:5
Phase value:0, Registered Parties:2, and Counter:5
Phase value:1, Registered Parties:2, and Counter:5
Phase value:1, Registered Parties:3, and Counter:5

-2147483648
Phase value:0, Registered Parties:1, and Counter:5
Phase value:0, Registered Parties:2, and Counter:5
Phase value:0, Registered Parties:3, and Counter:5
Phase value:0, Registered Parties:3, and Counter:5

但是对于一些奇怪的执行,它会产生如下输出

-2147483648
Phase value:0, Registered Parties:1, and Counter:5
Phase value:0, Registered Parties:2, and Counter:5
Phase value:0, Registered Parties:3, and Counter:5
Phase value:-2147483646, Registered Parties:0, and Counter:5

-2147483648
Phase value:0, Registered Parties:1, and Counter:5
Phase value:0, Registered Parties:2, and Counter:5
Phase value:-2147483646, Registered Parties:0, and Counter:5
Phase value:-2147483646, Registered Parties:0, and Counter:5

-2147483648
Phase value:0, Registered Parties:1, and Counter:5
Phase value:-2147483647, Registered Parties:0, and Counter:5
Phase value:-2147483647, Registered Parties:0, and Counter:5
Phase value:-2147483647, Registered Parties:0, and Counter:5

我不确定这是否可以成功复制,因为这种情况很少发生。否则想知道是什么错误导致了这种情况。
声明: Phaser 的初学者

4

1 回答 1

3

当您获得负值作为阶段值时 - 您的阶段终止。

方法的Java 文档摘录.getPhase()

返回当前阶段编号。最大阶段数是 Integer.MAX_VALUE,之后它会从零重新开始。终止时,阶段编号为负数,在这种情况下,可以通过 getPhase() + Integer.MIN_VALUE 获得终止之前的主要阶段。

那么,为什么会发生这种情况?

从相同的文档终止部分:

当 onAdvance 的调用返回 true 时触发终止。如果取消注册导致注册方的数量变为零,则默认实现返回 true。

在您的情况下,有时注册方的数量会变为 0。例如,当您注册主线程时,并且没有任何线程被注册 - 您取消注册主线程是可能的。这个案例是:

-2147483648
Phase value:0, Registered Parties:1, and Counter:5
Phase value:-2147483647, Registered Parties:0, and Counter:5
Phase value:-2147483647, Registered Parties:0, and Counter:5
Phase value:-2147483647, Registered Parties:0, and Counter:5

此外,还有另一种情况。摘自 baeldung

对到达AndAwaitAdvance() 的调用将导致当前线程在屏障上等待。如前所述,当到达方的数量与注册方的数量相同时,将继续执行。

这种情况可能是:

-2147483648
Phase value:0, Registered Parties:1, and Counter:5
Phase value:0, Registered Parties:2, and Counter:5
Phase value:-2147483646, Registered Parties:0, and Counter:5
Phase value:-2147483646, Registered Parties:0, and Counter:5
于 2019-02-07T09:33:22.320 回答