我知道CompletableFuture设计不会通过中断来控制其执行,但我想其中有些人可能会遇到此问题。 CompletableFuture是组成异步执行的一种很好的方法,但是考虑到您希望在取消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!!!");
    }
  }
}

最佳答案

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



甚至可能没有单独的线程在完成它(甚至可能有很多线程在工作)。即使存在,从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 - 如何中断CompletableFuture的基础执行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29013831/

10-12 00:18