java - ForkJoinPool 重置线程中断状态

标签 java multithreading java.util.concurrent forkjoinpool

我刚刚在取消 ForkJoinPool 返回的 Future 时注意到以下现象.给定以下示例代码:

ForkJoinPool pool = new ForkJoinPool();
Future<?> fut = pool.submit(new Callable<Void>() {

  @Override
  public Void call() throws Exception {
    while (true) {
      if (Thread.currentThread().isInterrupted()) { // <-- never true
        System.out.println("interrupted");
        throw new InterruptedException();
      }
    }
  }
});

Thread.sleep(1000);
System.out.println("cancel");
fut.cancel(true);

程序从不打印interruptedForkJoinTask#cancel(boolean) 的文档说:

mayInterruptIfRunning - this value has no effect in the default implementation because interrupts are not used to control cancellation.

如果 ForkJoinTasks 忽略中断,您还应该如何检查提交给 ForkJoinPool 的 Callables 中的取消?

最佳答案

发生这种情况是因为 Future<?>ForkJoinTask.AdaptedCallable延伸ForkJoinTask ,其取消方法为:

public boolean cancel(boolean mayInterruptIfRunning) {
    return setCompletion(CANCELLED) == CANCELLED;
}

private int setCompletion(int completion) {
    for (int s;;) {
        if ((s = status) < 0)
            return s;
        if (UNSAFE.compareAndSwapInt(this, statusOffset, s, completion)) {
            if (s != 0)
                synchronized (this) { notifyAll(); }
            return completion;
        }
    }
}

它不做任何中断,它只是设置状态。我想这是因为 ForkJoinPoolsFuture s 可能有一个非常复杂的树结构,并且不清楚以什么顺序取消它们。

关于java - ForkJoinPool 重置线程中断状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21320156/

相关文章:

java - Android Java : R. id.variable1..variable2..variable3..etc

java:在调度程序内对 lambda 表达式进行单元测试

java - 处理 2 - 线程会加速渲染许多对象吗?

python - threading.Condition.wait() 未捕获 SIGTERM

java - 如何实现异步队列?

java.util.concurrent.CyclicBarrier 类的方法 getNumberWaiting() 返回随机输出

java - 以编程方式从java在终端中执行命令

java - 无法找到 Javac 编译器

python - 我可以避免 Python 中的线程 UDP 套接字丢失数据吗?

java - 大小为 1 的信号量是最佳选择吗?