I have a server that has multiple worker threads implemented using java executorService (ie. a thread pool)
My problem is that I am not able to log at every second, the length of jobs waiting to be processed if there is no idle thread available from the thread pool.
NOTE : Logging is not my problem but I want to be able to see how many tasks/jobs are waiting to be processed by a worker thread, is there anyway to see the length of the waiting queue (not the thread pool ) inside executor service?
I have no idea how to implement this thing.
ThreadPoolExecutor is an ExecutorService to execute each submitted task using one of possibly several pooled threads, normally configured using Executors factory methods. It also provides various utility methods to check current threads statistics and control them.
You can wait for a task to finish in a ThreadPoolExecutor by calling the wait() module function.
The ThreadPoolExecutor
constructor accepts a BlockingQueue
parameter which is the Queue
implementation used to store the waiting jobs. You can request this queue using getQueue()
method, then check the size of the queue:
System.out.println("Number of waiting jobs: "+executor.getQueue().size());
Note that this method is not available in the ExecutorService
interface, thus it's better to construct the ThreadPoolExecutor
explicitly instead of using Executors.newFixedThreadPool
and friends:
ThreadPoolExecutor executor = new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
While Executors.newFixedThreadPool
in OpenJDK/OracleJDK does the same, it's not specified, thus using (ThreadPoolExecutor)Executors.newFixedThreadPool(nThreads)
may cause ClassCastException
in future Java versions or alternative JDK implementations.
If you can assume that the ExecutorService
implementation used by your server is ThreadPoolExecutor
, then you can use the method getQueue()
that returns the number of tasks that have not been assigned to a Worker
yet.
/**
* Returns the task queue used by this executor. Access to the
* task queue is intended primarily for debugging and monitoring.
* This queue may be in active use. Retrieving the task queue
* does not prevent queued tasks from executing.
*
* @return the task queue
*/
public BlockingQueue<Runnable> getQueue() {
return workQueue;
}
So you can run something like this:
if(LOGGER.isDebugEnabled()) {
LOGGER.debug(String.format("Pending tasks: %d", executor.getQueue().size()));
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With