В следующем примере кода я ввожу biconsumer
, который спит в течение 100 миллисекунд, как действие завершения набора завершаемого будущего. Я использовал метод whenCompleteAsync
, предоставив для использования отдельный executorService
. executorService
— это ThreadPoolExecutor
с размером основного пула 5, максимальным размером 5 и длиной очереди 1.
public class CompleteTest {
public static void main(String[] args) {
ExecutorService executorService = new ThreadPoolExecutor(5, 5, 10,
TimeUnit.SECONDS, new ArrayBlockingQueue<>(1));
ArrayList<CompletableFuture<String>> list = new ArrayList<>();
for (int i = 0; i <100; i++) {
CompletableFuture<String> stringCompletableFuture = new CompletableFuture<>();
stringCompletableFuture.whenCompleteAsync((e, a) -> {
System.out.println("Complete " + e);
try {
Thread.sleep(100);
} catch (InterruptedException e1) {e1.printStackTrace();}
}, executorService);
list.add(stringCompletableFuture);
}
for (int i = 0; i < list.size(); i++) {
list.get(i).complete(i + "");
}
}
}
Когда я запустил код, несмотря на то, что я завершаю 100 фьючерсов, печатается только 6 выходных данных. Это 5 основных потоков и 1 поток в очереди. Что происходит с остальными? Если другие исполняемые объекты не могут быть отправлены в службу-исполнитель из-за того, что очередь уже заполнена, не должно быть исключений.?
Вывод
Complete 0
Complete 1
Complete 2
Complete 3
Complete 4
Complete 5