什么可能是线程停在java.util.concurrent.ThreadPoolExecutor.getTask的原因

Nar*_*esh 5 java multithreading thread-dump executorservice threadpool

我有一个执行程序负责消耗来自ArrayBlockingQueue的消息.

new ThreadPoolExecutor(1, 1, 0L,
                TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1),  
                r -> {
                    return new Thread(r, "Request-Queue-Drainer");
                });
Run Code Online (Sandbox Code Playgroud)

Request-Queue-Drainer线程处于WAITING状态(虽然任务正在提交给该线程).以下是线程转储.

Name: Request-Queue-Drainer
State: WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@5b4757a2
Total blocked: 0  Total waited: 8

Stack trace: 
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
Run Code Online (Sandbox Code Playgroud)

线程处于等待状态的原因是什么?

Sol*_*low 4

由于队列为空,线程正在等待。这就是池线程所做的:它们从队列中选择任务并运行它们,当队列为空时,它们等待。


编辑:当队列为空时,还会发生其他情况:如果工作线程数量大于 超过时间单位ThreadPoolExecutor,则可以发送毒丸消息,导致池线程死亡。但在您的情况下不会发生这种情况,因为您将和设为相同的数字 (1)。corePoolSizekeepAlivemaximumPoolSizecorePoolSize


我不希望您的ThreadPoolExecutor行为与返回的行为有任何不同,Executors.newFixedThreadPool(1)除了您的只能有一个待处理的任务,并且它为池线程提供了一个特殊的名称。