当前位置: 首页 > 知识库问答 >
问题:

Java 8 CompletableFuture正在毫无必要地等待其他未来

漆雕奇逸
2023-03-14

下面我有一个简单的代码。所有的期货都应该同时开始future13应该在Future1和Future3完成后立即运行,但在日志中我看到它会等到Future1、Future2、Future3和Future4全部完成后才运行。为什么要等到第二和第四期呢?

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

import org.junit.Test;


public class Test1 {

    private void loop(Long id, int max) {
        try {
            for (int i = 0; i < max; i++) {
                System.out.println(id);
                Thread.sleep(100);
            }
        } catch (Throwable t) {
            System.out.println(t);
        }
    }

    private CompletableFuture<Void> createConfigFuture(Long id) {
        return CompletableFuture.supplyAsync(() -> {
            loop(id, 100);
            return null;
        });
    }

    @Test
    public void testMe() {
        CompletableFuture<Void> future1 = createConfigFuture(1L);
        CompletableFuture<Void> future2 = createConfigFuture(2L);
        CompletableFuture<Void> future3 = createConfigFuture(3L);
        CompletableFuture<Void> future4 = createConfigFuture(4L);

        try {
            CompletableFuture<Void> future13 = CompletableFuture.allOf(future1, future3)
                .thenApply(v -> {
                    loop(999L, 5);
                    return null;
                });
            CompletableFuture<Void> mainFuture = CompletableFuture.allOf(future13, future2, future4);
            mainFuture.get();

        } catch (InterruptedException | ExecutionException e) {
            System.out.println(e);
        }
    }
}

共有1个答案

萧业
2023-03-14

在JRE的默认fork joinExecutor中有一个队列来获取执行槽,所有异步任务都将在该执行槽上序列化。

任务#2在该执行者队列中位于任务#3之前,因此在观察任务#3的执行(以及完成任务#13的执行)之前,#2应该首先获得其执行槽。

这可能被视为链接到#2#3,但除此之外,任务之间不应存在任何额外的耦合。

 类似资料:
  • 首先,我决定让我的类阻塞(让消费者更容易使用,但对我来说可能更乏味)。而不是让使用者定义异步回调。这是一个好的设计模式吗?这样,用户可以获得预期的行为,但如果他们对线程被阻塞的时间不满意,则可以实现自己的多线程。 我有一个构造函数,它根据异步回调的结果在类中设置最后一个字段: 这不起作用,所以我使用了原子引用,并实现了一个阻塞循环,直到返回结果,如下所示: 这是阻止/检索结果的好方法吗?

  • 问题内容: 在JFrame中,当我单击“登录”时,我弹出另一个Jframe,即登录窗口。 在执行其他操作之前,如何使主Jframe等待登录Jframe退出? 问题答案: 只需使用模式对话框代替框架即可,这样在关闭对话框之前您无法做其他任何事情 有关说明,请参见http://mindprod.com/jgloss/modal.html;有关代码示例,请参见http://www.java2s.com/

  • 现在,如果传入false作为第三个参数,仍然会看到一个错误。理想情况下,我希望一个函数等待一个元素,如果它没有找到该元素就返回。

  • 我使用blocking queue(LinkedBlockingQueue)在几个线程之间同步数据。请看下图。 主线程是一个生产者,它产生对象,然后将它们放入每个消费者的队列中(线程2-10)。需要强调的是,每个消费者都有自己的队列,每个产生的对象都将进入所有消费者的队列。 生产者的运行速度比使用者快得多,因此我们可以假设在使用者运行期间队列不应该为空。当任何使用者的队列达到其容量时,生产者将被阻

  • 假设你在旅游,而且正在一辆在夜间运行的火车上。在夜间,如何在正确的站点下车呢?一种方法是整晚都要醒着,然后注意到了哪一站。这样,你就不会错过你要到达的站点,但是这样会让你感到很疲倦。另外,你可以看一下时间表,估计一下火车到达目的地的时间,然后在一个稍早的时间点上设置闹铃,然后你就可以安心的睡会了。这个方法听起来也很不错,也没有错过你要下车的站点,但是当火车晚点的时候,你就要被过早的叫醒了。当然,闹

  • 我有一段非基于演员的代码,它将一些操作委托给akka演员,我想无限期地等待这个演员的响应,我的意思是,直到这个演员返回一个响应,无论需要多长时间。问题是我不知道如何在未来无限期地等待attern.ask和wait.result方法。 我更喜欢这样的东西: 但这不起作用,因为Timeout不接受Duration对象作为构造函数参数,它只接受FiniteDuration对象。。。 任何想法? 干杯