Разница между использованием низкоуровневых API-интерфейсов параллелизма (таких как Thread) и других заключается не только в том виде работы, который вы хотите выполнить, но и в модели программирования, а также в том, насколько легко они настраивают ее. среда, в которой выполняется задача.
В общем случае рекомендуется использовать API более высокого уровня, например CompletableFuture
, вместо непосредственного использования Thread
s.
Я понимаю, что runAsyn () более эффективен для коротких / одноразовых параллельных задач
Ну, может быть, если вы звоните runAsync
, рассчитывая на то, что он будет использовать пул fork-join. Метод runAsync
перегружен методом, позволяющим указать java.util.concurrent.Executor
, с которым выполняется асинхронная задача.
Использование ExecutorService
для большего контроля над пулом потоков и использование CompletableFuture.runAsync
или CompletableFuture.supplyAsync
с указанной службой исполнителя (или нет) обычно предпочтительнее, чем создание и запуск объекта Thread
напрямую.
Нет ничего особенно за или против использования API CompletableFuture для долгосрочных задач. Но выбор, который вы выбираете для использования Thread
s, имеет и другие последствия, среди которых:
-
CompletableFuture
дает лучший API для программирования в реактивном режиме, не заставляя нас писать явный код синхронизации. (мы не получаем это при непосредственном использовании потоков)
- Интерфейс
Future
(который реализуется CompletableFuture
) дает другие дополнительные очевидные преимущества.
Итак, вкратце: вы можете (и, вероятно, должны, если рассматривается альтернатива Thread
API), использовать CompletableFuture
API для ваших долгосрочных задач. Чтобы лучше управлять пулами потоков, вы можете объединить их с сервисами executor.