đoạn mã nhỏ này không bao giờ kết thúc trên jdk8u45, và sử dụng để hoàn thành đúng trên jdk8u20:ForkJoinPool, Phaser và chặn được quản lý: chúng hoạt động như thế nào so với deadlocks?
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;
}
}
}
Các doc of phaser bang mà
Phasers cũng có thể được sử dụng bởi các công việc thực hiện trong một ForkJoinPool, mà sẽ đảm bảo tính song song đầy đủ để thực hiện các tác vụ khi những người khác bị chặn chờ đợi một giai đoạn để thăng tiến.
Tuy nhiên javadoc of ForkjoinPool#mangedBlock trạng thái:
Nếu chạy trong một ForkJoinPool, hồ bơi có thể đầu tiên được mở rộng để đảm bảo đủ song song
Chỉ có một có thể có. Vì vậy, tôi không chắc chắn liệu đây có phải là lỗi hay chỉ là mã không phụ thuộc vào hợp đồng của Phaser/ForkJoinPool: hợp đồng Phaser/ForkJoinPool có khó khăn như thế nào để ngăn chặn deadlocks?
cấu hình của tôi:
- Linux ADC 3.14.27-100.fc19.x86_64 # 1 SMP Wed 17 Tháng 12 19:36:34 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
- 8 lõi i7
Đã nộp: https://bugs.openjdk.java.net/browse/JDK-8080939 –
Ok cảm ơn. –
@AlekseyShipilev Có thể có thêm thông tin chi tiết về vấn đề này: Nếu tôi xóa phần comsumeCpu() hoặc giảm số lượng mã thông báo, thử nghiệm sẽ kết thúc đúng cách. Điều tương tự nếu tôi breakpoint trong ForkJoinPool # tryCompensate và bước thủ công –