[英]Shouldn't CompletableFuture.get(timeout) kill the task?
我正在運行兩個CompletableFuture
實例,它們等待 1 秒並向控制台打印一些內容。 我在 0.5 秒后打斷了第一個。 所以我希望只打印第二個,但實際上兩者都可以。 這里發生了什么?
這是代碼:
CompletableFuture<Void> c1 = CompletableFuture.runAsync(() -> {
System.out.println("Start CF 1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(1);
});
CompletableFuture<Void> c2 = CompletableFuture.runAsync(() -> {
System.out.println("Start CF 2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(2);
});
long start = System.currentTimeMillis();
try {
c1.get(500, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
System.out.println("CF interrupted after " + (System.currentTimeMillis() - start) + "ms");
}
c2.get();
它打印:
Start CF 1
Start CF 2
CF interrupted after 510ms
2
1
為什么你認為它應該? 如果 2 個消費者想要處理相同未來的結果,並且一個准備比另一個等待更長的時間怎么辦? 第一個會殺死第二個,它可能會及時完成。
無論如何,Java 沒有殺死任務的概念。 你能做的最好的事情就是設置一個標志要求它停止——一個中斷——但這依賴於任務檢查和尊重標志。 你的任務會,因為Thread.sleep()
隱式檢查中斷標志,但這是一個人為的例子,很多任務永遠不會檢查它。
get
方法的超時僅說明應該停止執行get
方法的時間。 它不影響結果的計算。 這適用於所有期貨。
因此,要中斷任務,您需要調用cancel(true)
但在CompletableFuture
的情況下甚至不會中斷任務:
參數:
mayInterruptIfRunning
- 此值在此實現中沒有影響,因為中斷未用於控制處理。”
如果你想要可中斷的任務,你需要使用ExecutorService
,但你也可以使用與CompletableFuture
的默認執行程序相同的線程池:
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService es = ForkJoinPool.commonPool();
Future<Void> c1 = es.submit(() -> {
System.out.println("Start CF 1");
Thread.sleep(1000);
System.out.println(1);
return null;
});
Future<Void> c2 = es.submit(() -> {
System.out.println("Start CF 2");
Thread.sleep(1000);
System.out.println(2);
return null;
});
long start = System.currentTimeMillis();
try {
c1.get(500, TimeUnit.MILLISECONDS);
} catch(TimeoutException e) {
c1.cancel(true);
System.out.println("timeout after "
+ (System.currentTimeMillis() - start) + "ms, canceled");
}
c2.get();
}
請注意,中斷可能仍然太慢,無法阻止1
的打印。 在我的機器上,我至少需要Thread.sleep(1100);
在打印前中斷任務。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.