Detection while idle thread ThreadPoolExecutor
I use ThreadPoolExecutor
to manage the number of threads, I can catch the new thread creation event for the ThreadPool via ThreadFactory->newThread()
But now I know how to catch the kill event of a Thread that stays dormant for 2 minutes like the following config.
I searched for a listener method but couldn't find it.
public abstract class ThreadPoolEventProcessor<E> implements ThreadFactory{
private BlockingQueue<Runnable> taskQueue;
private ThreadPoolExecutor executor;
protected ThreadPoolEventProcessor(int coreThreadSize, int maxQueueSize) {
taskQueue = new LinkedBlockingQueue<Runnable>(maxQueueSize);
executor = new ThreadPoolExecutor(coreThreadSize, coreThreadSize * 5, 2L, TimeUnit.MINUTES, taskQueue,this);
executor.prestartAllCoreThreads();
}
public Thread newThread(Runnable r) {
return new Thread(r, getWorkerName());
}
source to share
The ThreadPoolExecutor class has a set of workers, which are runnable classes that are managed by threads in the pool.
When the worker is executed, the workerDone callback is executed. And there you see the tryTerminate method being called. This is the method that decides whether to terminate the thread or not. You should be able to debug at this point
/**
* Performs bookkeeping for an exiting worker thread.
* @param w the worker
*/
void workerDone(Worker w) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
if (--poolSize == 0)
tryTerminate();
} finally {
mainLock.unlock();
}
}
/* Termination support. */
/**
* Transitions to TERMINATED state if either (SHUTDOWN and pool
* and queue empty) or (STOP and pool empty), otherwise unless
* stopped, ensuring that there is at least one live thread to
* handle queued tasks.
*
* This method is called from the three places in which
* termination can occur: in workerDone on exit of the last thread
* after pool has been shut down, or directly within calls to
* shutdown or shutdownNow, if there are no live threads.
*/
private void tryTerminate() {
if (poolSize == 0) {
int state = runState;
if (state < STOP && !workQueue.isEmpty()) {
state = RUNNING; // disable termination check below
addThread(null);
}
if (state == STOP || state == SHUTDOWN) {
runState = TERMINATED;
termination.signalAll();
terminated();
}
}
}
source to share
ThreadPoolExecutor
does not kill threads. It will fetch new streams from ThreadFactory
and have them run
a Worker
. This whole work cycle is doing a loop trying to extract Runnable
from the base BlockingQueue
.
If he gets one, he calls run
on it.
If you allowCoreThreadTimeOut
true
also have more employees than the principal, then the value is keepAliveTime
used to poll that base BlockingQueue
. If it poll
does null
, then the worker is (potentially) removed. Some additional cleanup is done, and calls to various methods are popped off the stack as methods return
until the method Worker#run()
completes and the containing stream ends.
Nowhere in this thread ThreadPoolExecutor
offers any notification hooks.
You can poll ThreadPoolExecutor#getPoolSize()
and ThreadPoolExecutor#getLargestPoolSize()
for information periodically.
source to share