java - Phaser 相位值逃逸

标签 java phaser

给定一个具有 main 方法的类,该方法初始化 Phaser,并创建(比如说)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 的初学者

最佳答案

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

摘自Java doc对于 .getPhase() 方法:

Returns the current phase number. The maximum phase number is Integer.MAX_VALUE, after which it restarts at zero. Upon termination, the phase number is negative, in which case the prevailing phase prior to termination may be obtained via getPhase() + Integer.MIN_VALUE.

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

来自同一个docs终止部分:

Termination is triggered when an invocation of onAdvance returns true. The default implementation returns true if a deregistration has caused the number of registered parties to become zero.

在您的情况下,有时注册方的数量会变为 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

此外,还有一种情况。 Excerpt from baeldung :

The call to the arriveAndAwaitAdvance() will cause the current thread to wait on the barrier. As already mentioned, when the number of arrived parties becomes the same as the number of registered parties, the execution will continue.

这种情况可能是:

-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

关于java - Phaser 相位值逃逸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54569475/

相关文章:

java - ForkJoinPool、Phaser 和托管阻塞 : to what extent do they works against deadlocks?

java - 使用和重用 Phaser 而不是 join()

Java:使用方法实现多维数组时出现一些错误

java - 我被 alpha-beta 剪枝算法实现所困扰

java - 如何在 PGP key 环和 Java keystore 文件之间进行转换?

java - 如何在 Apache Tiles 中注册属性渲染器?

java - 我如何知道最后一方何时触发 Phaser.arrive()?

java - Phaser 问题(使用 JSR166y 和最新版本 6 的 JDK)

java - 如何检查 Java 中所有的 boolean 值是真还是假?