当前位置: 首页 > 面试题库 >

如何取消Java 8可完成的未来?

傅嘉悦
2023-03-14
问题内容

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

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中的错误还是我的示例中的错误?


问题答案:

显然,这是故意的。方法CompletableFuture ::
cancel
的Javadoc 指出:

[参数:] mayInterruptIfRunning -这个值 没有 在该实施方式的效果,因为中断将不被用于控制处理。

有趣的是,方法ForkJoinTask ::
cancel
mayInterruptIfRunning 参数使用几乎相同的措词。

我对这个问题有一个猜测:

  • 中断 旨在与阻塞操作(例如 睡眠等待 或I / O操作)一起使用,
  • 但是 CompletableFutureForkJoinTask 都不打算与阻塞操作一起使用。

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



 类似资料:
  • 问题内容: 我有一个调用一些不检查线程中断的代码。调用之后,该方法将立即抛出(如预期的那样)。但是,由于后台任务的代码从不检查其线程是否被中断,因此它很乐意继续执行。 是否有等待后台任务 实际 完成的标准方法?我希望显示“正在取消…”消息或某种类似的内容,直到任务终止为止。(我确信如果有必要,我总是可以在worker类中使用一个标志来完成此操作,只需寻找其他解决方案即可。) 问题答案: 我玩了一点

  • 我的问题是如何使用Completable Future。 我有一个实现Callable的类。 早点用来做—— 这将返回

  • 我想要一个完整的未来,只发出完成的信号(例如,我没有返回值)。 我可以将CompletableFuture实例化为: 但是我应该向完整的方法提供什么呢?例如,我不能做

  • 我正在使用Java8,我想知道对3个异步作业强制超时的推荐方法,我将执行异步并从未来检索结果。请注意,所有3个作业的超时是相同的。如果超出时间限制,我还想取消作业。 我在想这样的事情: 像这样的东西有用吗?有更好的方法吗? 如何正确地取消未来?Javadoc说,线程不能被中断?所以,如果我取消一个未来,并调用,我会立即得到结果,因为线程不会被中断吗? 在等待结束后,是否建议使用run()或get(

  • 我在一个线程中创建了一个Kafka consumer实例,作为构造函数的一部分,在thread inside run方法中,我确实调用了不同的web服务,为了保持调用的非阻塞性,我正在使用completable future。我的问题是,我无法通过调用thenApply方法并传递Kafka consumer实例来发出commit,因为这会给我一个错误,即Kafka consumer不是线程安全的。

  • 我要做的是异步计算树结构的深度,我将有树的第一层,我想启动一个异步线程来分别计算每个节点的深度。 在计算过程中,树中显然可能有一个分叉,在这一点上,我想踢一个额外的线程来计算那个分支。 我已经得到了这个工作,但我需要做一些整理逻辑,当所有这些未来完成。但我对这一过程中产生的额外的可完成的未来感到困扰。 我会用什么方法来保存所有开始的CompletableFutures+那些动态创建的,并且在执行任