如果您要支持中斷,請不要使用join()
,而應使用get()
。他們基本上是相同的,除了:
join()
來自接口CompletionStage
而get()
自帶的接口形式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)
…
如果通過join()
更換get()
,中斷將確實不行。
我不知道這是你在找什麼:https://stackoverflow.com/questions/43389894/recursively-cancel-an-alloff-completablefuture/43391133#43391133 – Eugene
@Eugene謝謝你的鏈接。我知道'CompletableFuture :: cancel'不會中斷線程。我想要做的就是中斷一個阻塞'CompletableFuture :: join'操作的線程。也許我應該更清楚地描述我的問題。 – phil