Я заметил несколько необычное поведение с CompleteableFutures в Java 8 с потоковой передачей.
String [] arr = new String[]{"abc", "def", "cde", "ghj"};
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<String> lst =
Arrays.stream(arr)
.map(r ->
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
return "e";
} catch (Exception e) {
e.printStackTrace();
}
return null;
}, executorService)
)
.map(CompletableFuture::join)
.collect(Collectors.toList());
Этот код выше занимает 4 * 5000 = 20 секунд, поэтому это означает, что фьючерсы ждут друг друга.
String [] arr = new String[]{"abc", "def", "cde", "ghj"};
ExecutorService executorService = Executors.newFixedThreadPool(10);
List<CompletableFuture<String>> lst =
Arrays.stream(arr)
.map(r ->
CompletableFuture.supplyAsync(() -> {
try {
Thread.sleep(5000);
return "d";
} catch (Exception e) {
e.printStackTrace();
}
return null;
}, executorService)
)
.collect(Collectors.toList());
List<String> s =
lst
.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList());
System.out.println(s);
Этот код, однако, выполняется за 5 секунд, что означает, что фьючерсы работают параллельно.
Что я не понимаю: Во втором примере я получаю список фьючерсов в явном виде,затем выполните объединение, которое занимает 5 секунд, первый пример, через который я продолжаю потоковую передачу, и кажется, что оно ждет.
В чем причина этого?