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

如何中断CompletableFuture的基础执行

越风史
2023-03-14
问题内容

我知道CompletableFuture设计不能通过中断来控制其执行,但是我想其中有些人可能会遇到此问题。CompletableFutures是组成异步执行的一种非常好的方法,但是考虑到当您希望取消future时中断或停止基础执行时,我们该怎么做?还是我们必须接受,任何取消或手动完成的操作CompletableFuture都不会影响正在执行该操作的线程?

我认为,那显然是一项无用的工作,需要花费执行者的时间。我想知道在这种情况下哪种方法或设计可能会有所帮助?

更新

这是一个简单的测试

public class SimpleTest {

  @Test
  public void testCompletableFuture() throws Exception {
    CompletableFuture<Void> cf = CompletableFuture.runAsync(()->longOperation());

    bearSleep(1);

    //cf.cancel(true);
    cf.complete(null);

    System.out.println("it should die now already");
    bearSleep(7);
  }

  public static void longOperation(){
    System.out.println("started");
    bearSleep(5);
    System.out.println("completed");
  }

  private static void bearSleep(long seconds){
    try {
      TimeUnit.SECONDS.sleep(seconds);
    } catch (InterruptedException e) {
      System.out.println("OMG!!! Interrupt!!!");
    }
  }
}

问题答案:

A
CompletableFuture与可能最终完成的异步操作无关。

由于(与FutureTask此类不同)此类无法直接控制导致其完成的计算,因此取消被视为异常完成的另一种形式。方法cancel的作用与相同completeExceptionally(new CancellationException())

有可能甚至 一个单独的线程上完成它的工作(甚至有可能是 许多
线程在它的工作)。即使存在,也没有从CompletableFuture到任何引用它的线程之间的链接。

因此,您无法执行CompletableFuture任何操作来中断可能正在运行某些任务的线程来完成该任务。您必须编写自己的逻辑,该逻辑跟踪所有Thread获取到的引用的实例CompletableFuture以完成该实例。

这是我认为您可以摆脱的执行类型的示例。

public static void main(String[] args) throws Exception {
    ExecutorService service = Executors.newFixedThreadPool(1);
    CompletableFuture<String> completable = new CompletableFuture<>();
    Future<?> future = service.submit(new Runnable() {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                if (Thread.interrupted()) {
                    return; // remains uncompleted
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    return; // remains uncompleted
                }
            }
            completable.complete("done");
        }
    });

    Thread.sleep(2000);

    // not atomic across the two
    boolean cancelled = future.cancel(true);
    if (cancelled)
        completable.cancel(true); // may not have been cancelled if execution has already completed
    if (completable.isCancelled()) {
        System.out.println("cancelled");
    } else if (completable.isCompletedExceptionally()) {
        System.out.println("exception");
    } else {
        System.out.println("success");
    }
    service.shutdown();
}

这假定已将正在执行的任务设置为正确处理中断。



 类似资料:
  • 我是Java的新手,正在使用CompletableFutures执行异步操作,如下所示: 现在我需要修改它,这样,如果get失败,我就执行上面的链,但是如果成功,我就需要打破这个链,从函数返回一个包含ErrorResponse的任一对象。 如何才能打破这个加工链条?我知道我可以向链中的每个函数传递一个标志,并通过根据标志的值执行函数中的操作来实现这一点。我希望有更好的办法。 谢谢!!

  • 判断结构需要程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。 下面是大多数编程语言中典型判断结构的一般形式: C# 提供了以下类型的判断语句。点击链接查看每个语句的详细信息。 语句 描述 if 语句 一个if 语句由一个布尔表达式后跟一个或多个语句组成。 if…else 语句 一个if 语句后跟一个可选的 else 语句,else 语

  • 开始之前 我们在开始之前先来介绍在windows平台中常用到的几种脚本 Bat 这就是我们常用的Bat脚本,全名为批处理文件,脚本中就是我们在CMD中使用到的命令,这里提一个小问题: CMD的命令行执行命令的优先级是.bat > .exe,那么假如我放一个cmd.bat在system32目录下,那么优先执行的是cmd.bat,这里面的内容就变得不可描述起来了 VBscript 执行vbs就是常说的

  • 我知道设计无法通过中断来控制其执行,但我想你们中的一些人可能有这个问题。s是组成异步执行的非常好的方法,但考虑到当未来被取消时您希望底层执行被中断或停止的情况,我们如何做到这一点?或者我们必须接受任何取消或手动完成的都不会影响在那里工作以完成它的线程? 在我看来,这显然是一项无用的工作,需要执行者的时间。我想知道在这种情况下,什么方法或设计可能会有所帮助? 更新 这是一个简单的测试

  • 我正在尝试实现一个通用的REST客户端,如下所示。我有自己的模型将HTTP响应表示为response T。这里T是服务调用的返回类型,它可能只是T或Ts列表。下面的代码不编译,我需要帮助。 最终调用下面的方法,

  • 问题内容: 我最近在玩go,尝试制作一些服务器来响应tcp连接上的客户端。 我的问题是我该如何干净地关闭服务器并中断在以下调用中当前“被阻止”的go例程 func(* TCPListener)接受吗? 根据接受文件 Accept在侦听器接口中实现Accept方法;它等待下一个调用并返回通用Conn。 错误也很少被记录下来。 问题答案: 这是我一直在寻找的东西。也许将来会帮助某人。注意使用selec