我正在运行两个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
发布于 2022-12-01 11:21:35
你为什么认为应该这样?如果两个消费者想要处理同一个未来的结果,而其中一个准备等待的时间比另一个长呢?第一种可能会在第二种情况下杀死它,这可能是它及时完成的。
在任何情况下,Java都没有杀死任务的概念。您能做的最好是设置一个标志,要求它停止--一个中断--但是这依赖于任务检查和尊重标志。您的任务是这样做的,因为Thread.sleep()
隐式地检查中断标志,但这是一个人为的例子,很多任务都不会检查它。
发布于 2022-12-01 12:04:55
get
方法的超时只说明何时应该停止get
方法的执行。它不影响计算结果。这适用于所有未来。
因此,要中断任务,您需要调用cancel(true)
,但in case of 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);
来中断打印前的任务。
https://stackoverflow.com/questions/74640683
复制相似问题