Ten mały fragment kodu nigdy nie kończy się na jdk8u45 i stosowane prawidłowo zakończyć na jdk8u20:ForkJoinPool, Phaser i zarządzane blokowanie: w jakim stopniu działają one przeciwko impasom?
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;
}
}
}
W doc of phaser członkowskich, które
Fazery mogą być również wykorzystywane przez zadań realizujących w ForkJoinPool, który będzie zapewnić wystarczającą paralelność, aby wykonywać zadania, gdy inni są zablokowani, czekając na fazę, aby przejść dalej.
jednak javadoc of ForkjoinPool#mangedBlock stany:
Jeśli pracuje w ForkJoinPool, pula może najpierw zostać rozszerzony, aby zapewnić wystarczającą równoległość
tylko może. Nie jestem więc pewien, czy jest to błąd, czy tylko zły kod, który nie polega na umowie Phaser/ForkJoinPool: jak trudna jest umowa połączenia Phaser/ForkJoinPool, aby zapobiec zakleszczeniom?
Mój config:
- Linux ADC 3.14.27-100.fc19.x86_64 # 1 SMP Wed 17 grudnia 2014 19:36:34 UTC x86_64 x86_64 x86_64 GNU/Linux
- 8 rdzenie i7
Zapisano: https://bugs.openjdk.java.net/browse/JDK-8080939 –
OK, dzięki. –
@AlekseyShipilev Może więcej informacji na temat problemu: Jeśli usunę część comsumeCpu() lub zmniejszę liczbę tokenów, test zakończy się poprawnie. To samo, jeśli przerwę w ForkJoinPool # tryCompensate i krok ręcznie –