如何中断CompletableFuture :: join?

phi*_*hil 4 java multithreading interrupt java-8 completable-future

我发现,如果没有完成,它CompletableFuture::join似乎是不可中断的:

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

在上面的实现中,waitingGet(false)将忽略工作的中断标志Thread并继续等待.我想知道我怎么能打断Thread我打电话的地方CompletableFuture::join.

Did*_*r L 7

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

  • join()只在定义的CompletableFuture,而get()来自表格接口Future
  • join()包装异常,CompletionExceptionget()包装它们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();
}
Run Code Online (Sandbox Code Playgroud)

输出:

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)
    …
Run Code Online (Sandbox Code Playgroud)

如果替换get()join(),则中断确实不起作用.

  • 感谢您指出`join()`和`get()`之间的区别. (3认同)