【问题标题】:Run methods in asynchronously by using completablefuture使用 completablefuture 异步运行方法
【发布时间】:2021-06-13 17:39:14
【问题描述】:

我是 java 8 Completablefuture 的新手,我正在尝试按顺序调用异步方法

我的代码:

public class Main {

public static void main(String[] args) {
    System.out.println("CompletableFuture");
    ExecutorService e = Executors.newSingleThreadExecutor(r -> new Thread(r, "single Thread"));
    CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(()-> print("thread 1"),e);
    runT(voidCompletableFuture);
    voidCompletableFuture.thenRunAsync(()->print("Thread 3"));
    voidCompletableFuture.thenRun(e::shutdown);
}
public static void print(String threadName){
    for(int i=1;i<=10;i++) {
        System.out.println(threadName + ":" + i);
    }
}

public static void runT(@NotNull CompletableFuture<Void> ayns){
    ayns.thenRunAsync(()->print("Thread 2"));
}

}

但代码的工作方式不同,并以非顺序调用异步方法。

输出:

CompletableFuture
thread 1:1
thread 1:2
thread 1:3
thread 1:4
thread 1:5
thread 1:6
thread 1:7
thread 1:8
thread 1:9
thread 1:10
Thread 2:1
Thread 3:1
Thread 3:2
Thread 3:3
Thread 3:4
Thread 3:5
Thread 3:6
Thread 3:7
Thread 3:8
Thread 3:9
Thread 3:10
Thread 2:2
Thread 2:3
Thread 2:4
Thread 2:5
Thread 2:6
Thread 2:7
Thread 2:8
Thread 2:9
Thread 2:10

根据代码逻辑“线程1”、“线程2”、“线程3”需要执行但在输出中“线程1”被调用然后“线程2”被调用但“线程2”没有完成但“线程3” " 开始执行,只有 "Thread 3" 完全执行,然后 "Thread 2" 重新开始。

我的问题是为什么会这样?如果我的实现不正确,请建议我在 java 8 中实现此功能的任何方法。

【问题讨论】:

  • 您已将 3 个不同的阶段链接到您的 voidCompletableFuture。当然,它们以任何顺序运行,您期望什么?

标签: java multithreading java-8 completable-future


【解决方案1】:

您将 3 个不同的阶段链接到一个 voidCompletableFuture

  • 两个thenRunAsync
  • 一个thenRun

当然,它们以一些未定义的顺序运行。如果您确实想要顺序,请不要忽略这些方法的结果并将一些相关操作链接到它们。例如:

voidCompletableFuture
    .thenRunAsync(()->print("Thread 3"))
    .thenRun(e::shutdown);

thenRunAsyncthenRun 这样的方法有一个返回类型 - 不要忽略它(就像你一样)。


在你的情况下:

public static CompletableFuture<Void> runT(@NotNull CompletableFuture<Void> ayns){
   CompletableFuture<Void> result = ayns.thenRunAsync(()->print("Thread 2"));
   return result;
}

现在正确链接它:

CompletableFuture<Void> voidCompletableFuture = CompletableFuture.runAsync(()-> print("thread 1"),e);
CompletableFuture<Void> newF = runT(voidCompletableFuture);
newF.thenRunAsync(()->print("Thread 3"));
    .thenRun(e::shutdown);

【讨论】:

  • 嗨,Eugene,当尝试以下操作时,我得到了正确的结果。 voidCompletableFuture .thenRunAsync(()->print("Thread 1")) .thenRunAsync(()->print("Thread 2")) .thenRun(e::shutdown);但是,如果我将 voidCompletableFuture 作为参数传递给另一个方法,则意味着它不会保持顺序。那是我的问题
  • @SridharKaruppusamy 你看到编辑了吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多