join
внутри Future
нужно использовать очень аккуратно, вот пример дэдлока
import java.util.concurrent.*;
public class Program
{
public static void main(String[] args) throws Exception {
var p = Executors.newSingleThreadExecutor();
var someCompletionStage = CompletableFuture
.supplyAsync(()->{
try { Thread.sleep(1000); } catch (Exception ex) {}
return "hi!";
}, p)
.thenApplyAsync(s -> {
try { Thread.sleep(1000); } catch (Exception ex) {}
return s;
}, p);
CompletableFuture.runAsync(() -> {
String string = someCompletionStage.join();
System.out.println(string);
}, p)
.join();
System.out.println("bye!");
p.shutdown();
}
}
Происходит это потому, что "третий" CompletableFuture.runAsync
успевает вклиниться между "первым" supplyAsync
и "вторым" thenApplyAsync
, блокирует поток джойном, поэтому вторая часть уже никогда не выполнится.
С цепочкой вызовов, естественно, дэдлок не случится.