В вашем примере у вас есть 3 CompletableFuture
s, которые находятся в игре:
- тот, который вернулся
runAsync()
- тот, который вернулся
myMethod()
- тот, который вернулся
thenCompose()
У вас также есть 4 задачи, которые нужно выполнить:
- тот, который передан
runAsync()
, будет выполнен на данном исполнителе и обработает будущее 1;
- тот, который вызывает
myMethod()
из thenCompose()
для создания будущего 2, может быть запущен на любом исполнителе, используйте thenComposeAsync()
, чтобы явно выбрать один;
- тот, который завершит будущее 2, возвращаемый
myMethod()
- это будет контролироваться внутри самого myMethod()
;
- тот, который завершит будущее 3, возвращенное
thenCompose()
- это обрабатывается внутренне и будет зависеть от порядка выполнения (например, если myMethod()
вернет уже завершенное будущее, оно также завершит первое).
Как видите, задействованы несколько задач и исполнителей, но вы всегда можете контролировать исполнителей, используемых на зависимых этапах, используя *Async()
варианты. Единственный случай, когда вы на самом деле не контролируете его, это 4-й случай, но это дешевая операция, если зависимые этапы также используют варианты *Async()
.