Допустим, у меня есть длительная операция, от которой я хотел бы получить результат или тайм-аут, если это займет слишком много времени.
Есть 2 разные версии, которые я хотел бы сравнить:
1) Когда мы вызываем poll
, мы проверяем, были ли какие-либо элементы поставлены в очередь во внутреннюю очередь блокировки
ExecutorService executorService = Executors.newFixedThreadPool(4);
CompletionService<String> completionService = new ExecutorCompletionService<>(executorService);
Future<String> future = completionService.submit(() -> {...});
final Future<String> result = completionService.poll(30, TimeUnit.SECONDS);
if (result != null) {
...
}
2) Когда мы вызываем get
, у нас есть реализация из FutureTask
для ожидания
ExecutorService executorService = Executors.newFixedThreadPool(4);
Future<String> future = executorService.submit(() -> {...});
try {
String result = future.get(30, TimeUnit.SECONDS);
} catch (TimeoutException e) {
...
}
По сути, в обеих версиях мы ждем, пока будущее завершит свое выполнение, но внутренняя реализация отличается. Будет ли разница в производительности? Я видел этот ответ, который сравнивает CompletionService
с CompletableFuture
и говорит, что должно быть https://stackoverflow.com/a/52980559/2055854 а>. Будет ли то же самое для реализации FutureTask
? Если да, было бы здорово услышать лучшее объяснение, почему.
FutureTask
или ждетеBlockingQueue
. Таким образом, второй пример проще и не создает и не используетBlockingQueue
. Единственное, что может быть более эффективным, это вообще не ждать, т.е.CompletableFuture.supplyAsync(() -> {...}, executorService).thenAccept(result -> { … });
выполнит потребитель, как только результат будет доступен, поэтому ни один поток не будет ждать. - person Holger   schedule 31.01.2020