What can explain a deadlock only occuring with virtual threads?

349 views Asked by At

I am encountering a deadlock when using an executor based on virtual threads. The issue arises when I am using 50 threads but not at 20. The issue does not shows up when I am not using virtual threads.

I am looking for insights and recommendations on troubleshooting and resolving the deadlock problem unique to virtual threads, especially considering the absence of this issue when virtual threads are not in use.

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

vs

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

The executor service is wrapped in a CompletionService.

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

The main thread seems to wait indefinitely on the first call completionService.take().

Here is the relevant snippet of the code.

        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);
                }
            }
        }

What could be the cause of the issue?

EDIT: this seems to be caused by an HTTP connection pool issue. I am using httpclient-4.5.14.

Internally this client use synchronized which according to my understanding is an issue for Virtual Threads as it pins the platform thread. I don't know if it can be the cause of the deadlock as I can't seen any error, neither weird stuff in the thread dump.

enter image description here

Trials: I tried to use the -Djdk.tracePinnedThreads=full to check for pinned thread but no luck until now.

0

There are 0 answers