implementacja przyklady05.Utils.awaitAll dwa razy czyta listę
Implementacja przyklady05.Utils.awaitAll
specyficznie się zachowuje jak ktoś zmienia podaną listę futures. Zwracany future czeka na to co jest w niej w danym momencie (allOf), po czym znowu czeka na wszystkie (join):
CompletableFuture
.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(ignored ->
Arrays.stream(futures)
.map(CompletableFuture::join)
.collect(Collectors.toList()));
Niechcący to powoduje to że działają programy które nie powinny działać: dostałem od studenta rozwiązanie które wkłada do listy zadanie A, po czym robi awaitAll na tej liście. W kodzie A tworzy nowe async zadania B1, B2, ... i nie czeka na nie tylko dokłada je do listy. Okazuje się że future zwracany przez awaitAll zaczeka na B1, B2, ..., mimo że awaitAll zreturnował przed dodaniem ich do listy.
W wersji z varargs chyba też jest problem jeśli ktoś zmieni elementy w podanej tablicy.
Proponuję dopisać w wersji varargs po prostu final var futures_copy = futures.clone()
, w wersji z List final List<CompletableFuture<T>> futures_copy = new ArrayList<CompletableFuture<T>>(futures);
(albo wołać wersję varargs, ale trzeba wtedy @SuppressWarnings("unchecked")
).