我在下面有这个简单的代码。所有期货应同时开始。 future13
应该在期货1和3完成之后立即运行,但是在日志中,我看到它一直等到期货1、2、3和4全部完成之后。为什么要等待期货2和4?
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);
}
}
}
答案 0 :(得分:1)
JRE的默认fork-join Executor
中有一个队列来获取执行插槽,所有异步任务都将在该插槽上进行序列化。
在该#2
队列中,任务#3
在任务Executor
的前面,因此在观察任务#3
(以及分别在完成任务#13
)#2
应该首先获得其执行位置。
这可能被视为#3
链接到#2
,但除此之外,任务之间不应有任何其他耦合。