从调用线程运行 CompletableFuture.thenAccept?

Zhr*_*hro 4 java concurrency multithreading

我想调用CompletableFuture.supplyAsync()将阻塞任务委托给另一个线程。一旦该任务完成,我希望CompletableFuture.thenAccept消费者在调用线程的上下文中运行。

例如:

// Thread 1

CompletableFuture.supplyAsync(() -> {
   // Thread 2

   return BlockingMethod();
}).thenAccept((
   Object r) -> {

   // Thread 1
});
Run Code Online (Sandbox Code Playgroud)

以下代码建议CompletableFuture.thenAccept在其自己的线程中运行;可能与CompletableFuture.supplyAsync运行时获得相同线程 ID 的池相同:

System.out.println("Sync thread supply " + Thread.currentThread().getId());

CompletableFuture.supplyAsync(() -> {

   System.out.println("Async thread " + Thread.currentThread().getId());

   try {
      Thread.sleep(2000);
   }
   catch (Exception e) {
      e.printStackTrace();
   }

   return true;
}).thenAccept((
   Boolean r) -> {

   System.out.println("Sync thread consume " + Thread.currentThread().getId());
});

Thread.sleep(3000);
Run Code Online (Sandbox Code Playgroud)

是否可以CompletableFuture.thenAccept与调用线程同时运行?

Sot*_*lis 5

CompletableFuture只会执行Consumer与您注册thenAccept时的接收器CompletableFuture(通过返回一个supplyAsync)完成,因为它需要它与完成值。

如果接收器CompletableFuturethenAccept被调用时完成,则将Consumer在调用线程中执行。否则,它将在完成Supplier提交到的任何线程上执行supplyAsync

是否可以CompletableFuture.thenAccept与调用线程同时运行?

这是一个令人困惑的问题,因为一个线程一次只能运行一件事。单个线程没有并发Concurrently是一个跨越多个线程的属性。

如果您希望Consumer运行在调用 的同一线程上thenAccept,则join在 上CompletableFuture,阻塞此线程,直到未来完成。然后,您可以Consumer自己执行或调用thenAccept为您执行它。

例如

CompletableFuture<Boolean> receiver = CompletableFuture.supplyAsync(() -> {
    System.out.println("Async thread " + Thread.currentThread().getId());

    try {
        Thread.sleep(2000);
    } catch (Exception e) {
        e.printStackTrace();
    }

    return true;
});

receiver.join();
Consumer<Boolean> consumer = (Boolean r) -> {
    System.out.println("Sync thread consume " + Thread.currentThread().getId());
};

consumer.accept(receiver.get());
Run Code Online (Sandbox Code Playgroud)

(省略异常处理。)


如果您希望ConsumerSupplier提供的 to并行运行supplyAsync,那是不可能的。那Consumer是为了消耗Supplier. 该值在Supplier完成之前不可用。