java - 如何中断 CompletableFuture::join?

标签 java multithreading java-8 interrupt completable-future

我发现 CompletableFuture::join 在未完成时似乎不可中断:

// CompletableFuture::join implementation from JDK 8 sources
public T join() { 
    Object r;
    return reportJoin((r = result) == null ? waitingGet(false) : r);
}

在上面的实现中,waitingGet(false)会忽略正在工作的Thread的中断标志并继续等待。我想知道如何中断调用 CompletableFuture::joinThread

最佳答案

如果要支持中断,请不要使用 join(),请改用 get()。基本上它们是相同的,除了:

  • join() 仅在 CompletableFuture 中定义,而 get() 来自接口(interface) Future
  • join() 将异常包装在 CompletionException 中,而 get() 将它们包装在 ExecutionException
  • get() 可能会被中断,然后会抛出一个 InterruptedException

请注意,您中断的是Thread,而不是Future。例如,以下代码在等待 myFuture.get() 时中断主线程:

CompletableFuture<Void> myFuture = new CompletableFuture<>();
Thread mainThread = Thread.currentThread();
CompletableFuture.runAsync(() -> {
    try {
        Thread.sleep(1000);
        System.out.println("Interrupting…");
        mainThread.interrupt();
        Thread.sleep(1000);
        System.out.println("Completing");
        myFuture.complete(null);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
});
try {
    myFuture.get();
    System.out.println("Get succeeded");
} catch (Exception e) {
    System.out.println("Get failed");
    e.printStackTrace();
}

输出:

Interrupting…
Get failed
java.lang.InterruptedException
    at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:347)
    at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1895)
    at CompletableFutureInteruption.main(CompletableFutureInteruption.java:37)
    …

如果将get()替换为join(),中断确实不会起作用。

关于java - 如何中断 CompletableFuture::join?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44231376/

相关文章:

java - cmd “class not found”

Java:在原始线程的上下文中从另一个线程调用回调

java - 使用 JavaStreams 过滤复杂列表元素 - 代码优化

parallel-processing - 可拆分性和状态性对 Stream 并行处理的影响

java - 使用jena修改预定义本体

java - APICall 响应解析数据失败

Java隐藏从数据库中检索到的空值

java - ThreadMXBean.getThreadCpuTime() 是否包括在所有状态下花费的时间,或仅包括 RUNNABLE?

java - Java中什么情况下需要同步数组?

java - 仅过滤请求中存在的参数