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

标签 java java-8 phaser forkjoinpool

这个小代码片段永远不会在 jdk8u45 上完成,并且曾经在 jdk8u20 上正确完成:

public class TestForkJoinPool {

    final static ExecutorService pool = Executors.newWorkStealingPool(8);
    private static volatile long consumedCPU = System.nanoTime();

    public static void main(String[] args) throws InterruptedException {
        final int numParties = 100;
        final Phaser p = new Phaser(1);
        final Runnable r = () -> {
            p.register();
            p.arriveAndAwaitAdvance();
            p.arriveAndDeregister();
        };

        for (int i = 0; i < numParties; ++i) {
            consumeCPU(1000000);
            pool.submit(r);
        }

        while (p.getArrivedParties() != numParties) {}
    }

    static void consumeCPU(long tokens) {
        // Taken from JMH blackhole
        long t = consumedCPU;
        for (long i = tokens; i > 0; i--) {
            t += (t * 0x5DEECE66DL + 0xBL + i) & (0xFFFFFFFFFFFFL);
        }
        if (t == 42) {
            consumedCPU += t;
        }
    }
}

doc of phaser指出

Phasers may also be used by tasks executing in a ForkJoinPool, which will ensure sufficient parallelism to execute tasks when others are blocked waiting for a phase to advance.

然而 javadoc of ForkjoinPool#mangedBlock状态:

If running in a ForkJoinPool, the pool may first be expanded to ensure sufficient parallelism

只有一个可能。所以我不确定这是一个错误,还是只是不依赖于 Phaser/ForkJoinPool 契约的错误代码:Phaser/ForkJoinPool 组合的契约在防止死锁方面有多难?


我的配置:

  1. Linux adc 3.14.27-100.fc19.x86_64 #1 SMP Wed Dec 17 19:36:34 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
  2. 8 核 i7

最佳答案

看起来您的问题来自 JDK 8u20 和 8u45 之间的 ForkJoinPool 代码更改。

在 u20 中,ForkJoin 线程在被回收之前始终存活至少 200 毫秒(请参阅 ForkJoinPool.FAST_IDLE_TIMEOUT)。

在 u45 中,一旦 ForkJoinPool 达到其目标并行度加上 2 个额外的线程,线程将在没有等待的情况下用完工作后立即死亡。 您可以在 ForkJoinPool.java(第 1810 行)的 awaitWork 方法中看到此更改:

    int t = (short)(c >>> TC_SHIFT);  // shrink excess spares
    if (t > 2 && U.compareAndSwapLong(this, CTL, c, prevctl))
        return false; 

您的程序使用 Phasers 任务来创建额外的 worker。每个任务都会产生一个新的补偿工作人员,该工作人员旨在接手下一个提交的任务。
但是,一旦达到目标并行度 + 2,补偿工作人员将立即死亡而无需等待,并且没有机会接手随后将立即提交的任务。

希望对您有所帮助。

关于java - ForkJoinPool、Phaser 和托管阻塞 : to what extent do they works against deadlocks?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30392753/

相关文章:

java - Java 8 是否提供了一种重复值或函数的好方法?

java - 快速 Java 匿名函数/类问题

java - Phaser 相位值逃逸

java - Google Glass OAuth无效客户端

java - 如何在Python中编写可以在Java中本地读取的浮点值?

java - java8流下载文件的有效方法

java - 嵌套 if-object-null-return 方法提取或替代 Sonar 认知复杂性

java - ArrayOutOfBoundsException : asm. ClassReader.readClass(未知来源)

java - 将线程注册到 Phaser

Java: jsr166y Phaser 教程/讲解