如何取消Java 8可完成的未来? [英] How to cancel Java 8 completable future?

查看:125
本文介绍了如何取消Java 8可完成的未来?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在玩Java 8可完成的期货。我有以下代码:

I am playing with Java 8 completable futures. I have the following code:

CountDownLatch waitLatch = new CountDownLatch(1);

CompletableFuture<?> future = CompletableFuture.runAsync(() -> {
    try {
        System.out.println("Wait");
        waitLatch.await(); //cancel should interrupt
        System.out.println("Done");
    } catch (InterruptedException e) {
        System.out.println("Interrupted");
        throw new RuntimeException(e);
    }
});

sleep(10); //give it some time to start (ugly, but works)
future.cancel(true);
System.out.println("Cancel called");

assertTrue(future.isCancelled());

assertTrue(future.isDone());
sleep(100); //give it some time to finish

使用runAsync我安排执行等待锁存器的代码。接下来我取消了未来,期望被抛入中断的异常。但似乎线程在await调用上仍然被阻塞,即使未来被取消(断言传递),也永远不会抛出InterruptedException。使用ExecutorService的等效代码按预期工作。这是CompletableFuture或我的例子中的错误吗?

Using runAsync I schedule execution of a code that waits on a latch. Next I cancel the future, expecting an interrupted exception to be thrown inside. But it seems that the thread remains blocked on the await call and the InterruptedException is never thrown even though the future is canceled (assertions pass). An equivalent code using ExecutorService works as expected. Is it a bug in the CompletableFuture or in my example?

推荐答案

显然,这是故意的。方法的Javadoc CompletableFuture :: cancel 状态:

Apparently, it's intentional. The Javadoc for the method CompletableFuture::cancel states:


[参数:] mayInterruptIfRunning - 此值因为中断不用于控制处理。

[Parameters:] mayInterruptIfRunning - this value has no effect in this implementation because interrupts are not used to control processing.

有趣的是,方法 ForkJoinTask :: cancel 对参数 mayInterruptIfRunning <使用几乎相同的措辞/ em>。

Interestingly, the method ForkJoinTask::cancel uses almost the same wording for the parameter mayInterruptIfRunning.

我猜这个问题:


  • 中断旨在与阻塞操作一起使用,例如 sleep wait 或I / O操作,

  • CompletableFuture ForkJoinTask 都不适用于阻止操作。

  • interruption is intended to be used with blocking operations, like sleep, wait or I/O operations,
  • but neither CompletableFuture nor ForkJoinTask are intended to be used with blocking operations.

CompletableFuture 应该创建一个新的 CompletionStage 而不是阻塞,而cpu绑定任务是fork-join的先决条件模型。因此,使用中断与其中任何一个都会失败他们的目的。而另一方面,它可能会增加复杂性,如果按预期使用则不需要。

Instead of blocking, a CompletableFuture should create a new CompletionStage, and cpu-bound tasks are a prerequisite for the fork-join model. So, using interruption with either of them would defeat their purpose. And on the other hand, it might increase complexity, that's not required if used as intended.

这篇关于如何取消Java 8可完成的未来?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆