无法异步执行作业

Cannot execute job asynchronously

提问人:Hzt 提问时间:10/30/2023 最后编辑:Mark RotteveelHzt 更新时间:10/30/2023 访问量:49

问:

我有一个非常令人困惑的问题。我正在组合几个,分别需要 4、6 和 8 秒。我期望它们以异步方式执行,这意味着总共只需要 8 秒(最长)。但是,当我运行代码时,需要 18 (4 + 6 + 8) 秒才能完成。Uni<Integer>

我哪里做错了?

我的代码:

public Uni<Integer> asyncTask(int idx, int delay) {
    return Uni.createFrom().item(Unchecked.supplier(() -> {
        // Perform your asynchronous operation here
        // Simulate a delay
        try {
            Thread.sleep(delay);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(new Date() + " " + delay);
        return idx; // Example result
    }));
}

public void executeAsyncTasks() {
    Date startTime = new Date();
    Uni.combine().all()
            .unis(asyncTask(1, 4000), asyncTask(2, 6000), asyncTask(3, 8000))
            .asTuple()

            // Subscribe (which will trigger the calls)
            .subscribe().with(tuple -> {
                System.out.println("item 1: " + tuple.getItem1());
                System.out.println("item 2: " + tuple.getItem2());
                System.out.println("item 3: " + tuple.getItem3());
                Date finishTime = new Date();
                System.out.println(finishTime.getTime() - startTime.getTime());
            });
}
Java 异步 Quarkus 叛变

评论


答:

1赞 Pendula 10/30/2023 #1

尽管 Quarkus 支持异步编程,但它基于事件循环线程模型,其中承载任务/事件的 I/O 线程很少。因此,最重要的事情之一就是不要阻塞 I/O 线程。这正是您在代码中所做的Thread.sleep()

您可以在此处找到更多详细信息和解释:

https://quarkus.io/guides/quarkus-reactive-architecture

https://quarkus.io/guides/mutiny-primer

3赞 Ladicek 10/30/2023 #2

您不希望异执行这些任务。您希望它们同时执行。在Quarkus中,有两种方法可以同时运行多个任务:

  • 使用非阻塞编程,其中多个任务在单个线程上并发执行,因为它们交错
  • 使用线程,其中每个任务都在自己的线程上运行

你显然没有使用非阻塞编程,因为你阻塞了 ()。Thread.sleep()

您也不要使用多个线程。您可能希望 Mutiny 为每个任务创建一个线程,但这不是响应式编程库的工作方式。你必须明确地要求这一点。