CompletableFuture не закрывает потоки - PullRequest
0 голосов
/ 05 сентября 2018

У меня проблема с моим асинхронным методом. Работает нормально, но количество потоков постоянно увеличивается.

Вот мой пример кода:

ExecutorService executorService = Executors.newFixedThreadPool(marketplaces.size());

public void createCache() {
        List<CompletableFuture<List<OrderResponseDto>>> futures = marketplaces.stream().map(
                m -> CompletableFuture.supplyAsync(m::trades, executorService)
                        .applyToEither(timeoutAfter(TIMEOUT_SECONDS, TimeUnit.SECONDS), Function.identity())
                        .exceptionally(error -> {
                            log.warn("Trades failed {}", error);
                            return Collections.emptyList();
                        })
        ).collect(toList());

    Map<TradePlatform, List<OrderResponseDto>> collect = futures.stream()
            .map(CompletableFuture::join)
            .flatMap(List::stream)
            .collect(groupingBy(OrderResponseDto::getMarketplace));
    marketplaceCache.putAll(collect); 
}

Полный проект, расположенный на GitHub: https://github.com/rublin/KarboMarketplaceExplorer

Прямая ссылка на класс

Вот тест , который охватил это поведение.

1 Ответ

0 голосов
/ 05 сентября 2018

Чтобы подвести итоги, перечисленные в комментариях:

Это утечка потока, вызванная методом timeoutAfter() (см. Источник, который вы указали).

Этот метод создает новый пул потоков с одним потоком каждый раз, когда он вызывается, но нет ничего, чтобы закрыть пул и, следовательно, остановить потоки.

Поскольку timeoutAfter() вызывается один раз (вероятно) для каждого CompletableFuture, созданного в createCache(), общее число потоков просто увеличивается.

Исправление заключается в том, чтобы повторно использовать пулы потоков в течение всего жизненного цикла приложения и убедиться, что они правильно закрыты при выходе (еще одним соображением было бы то, как определить размер пулов потоков и какой тип пулов потоков использовать, особенно если заданные им задачи могут блокироваться).

Также см. Комментарии Натана Хьюза к вопросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...