Чем можно объяснить взаимоблокировку, возникающую только в виртуальных потоках?

Я столкнулся с тупиком при использовании исполнителя на основе виртуальных потоков. Проблема возникает, когда я использую 50 потоков, но не 20. Проблема не проявляется, когда я не использую виртуальные потоки.

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

      private static final ExecutorService taskExecutor =0 Executors.newFixedThreadPool(CONCURRENT_WORKERS);

против

      private static final ExecutorService taskExecutor = Executors.newFixedThreadPool(CONCURRENT_WORKERS, Thread.ofVirtual().factory());

Служба исполнителя заключена в CompletionService.

      private static final CompletionService<Data> completionService = new ExecutorCompletionService<>(taskExecutor)

Кажется, что основной поток ждет бесконечно при первом вызовеcompletionService.take().

Вот соответствующий фрагмент кода.

              for (int taskIndex = 0; taskIndex < TASK_COUNT; taskIndex++) {
            completionService.submit(this::doTask);
        }
        log.info("Submitted all {} tasks to the executor, waiting.", TASK_COUNT);
        try {
            for (int taskIndex = 0; taskIndex < TASK_COUNT; taskIndex++) {
                Future<Data> future = completionService.take();
                try {
                    var data = future.get();
                    storeData(data);
                } catch (ExecutionException e) {
                    log.warn("Error executing task", e);
                }
            }
        }

В чем может быть причина проблемы?

РЕДАКТИРОВАТЬ: похоже, это вызвано проблемой пула HTTP-соединений. Я использую httpclient-4.5.14.

Внутренне этот клиент используетsynchronizedчто, насколько я понимаю, является проблемой для виртуальных потоков, поскольку они закрепляют поток платформы. Я не знаю, может ли это быть причиной тупика, поскольку я не вижу ни ошибок, ни странных вещей в дампе потока.

Испытания: я пытался использовать -Djdk.tracePinnedThreads=full для проверки закрепленной темы, но до сих пор безуспешно.

0 ответов

Другие вопросы по тегам