I have an executor which is responsible for consuming messages from a ArrayBlockingQueue.
new ThreadPoolExecutor(1, 1, 0L,
TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<>(1),
r -> {
return new Thread(r, "Request-Queue-Drainer");
});
Request-Queue-Drainer thread is in WAITING state (Though tasks are being submitted to this thread). The following is the thread-dump.
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)
What could be the reason for the thread to be in waiting status?
The thread is waiting because the queue is empty. That's what pool threads do: They pick tasks from the queue and run them, and when the queue is empty, they wait.
Edit: There's something else that can happen when the queue is empty: The ThreadPoolExecutor
can send in a poison pill message that causes a pool thread to die if the number of workers has been greater than the corePoolSize
for more than keepAlive
time units. That won't happen in your case though because you set the maximumPoolSize
and the corePoolSize
to the same number (1).
I don't expect your ThreadPoolExecutor
to behave any differently from the one that would be returned by Executors.newFixedThreadPool(1)
except that yours can only have one pending task, and it gives the pool thread a special name.