KeepAliveTime is a parameter that basically removes all threads except the core thread when they exceed their wait time and then we’re going to talk about how threads are created and executed and then how the wait time is removed and we’re going to talk about the core parameters of the two thread pools, okay
- HashSet Workers Collection of work classes
Worker is actually a thread stored in the thread pool that implements the Runnable interface. When 10 threads are opened in the thread pool, 10 Worker classes will be created, which will be stored in the workers work class set. The Worker class mainly has the following two core parameters
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
/** The thread that executes Worker */
final Thread thread;
/** where threads are passed to the thread pool by the user */
Runnable firstTask;
Worker(Runnable firstTask) {
setState(-1); // inhibit interrupts until runWorker
this.firstTask = firstTask;
// Add the worker to the thread and execute the firsttask.run method of the worker
this.thread = getThreadFactory().newThread(this);
}
Copy the code
- BlockingQueue< Runnable > workQueue Wait queue
When a thread reaches the core number of threads, it will put the queue to wait for execution
execute(Runnable command)
The first time you execute the thread pool’s execute will execute this code because the current thread count is smaller than the core thread count unless the core thread count is set to 0
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
Copy the code
The core here is the addWorker method which will pass in the thread command that needs to be executed into the worker worker class and then into the Workers worker class collection and then start the worker thread
// Just pull the core code
// firstTask is the thread passed in to execute(Runnable command)
w = new Worker(firstTask);
final Thread t = w.thread;
workers.add(w);
t.start();
Copy the code
Then look at the Worker’s run method, which executes the runWorker method first and then executes the thread that needs to be executed in the method. There are two lines of core code here
If task is not empty, the task is executed. If task is empty, getTask() obtains the threads that need to be executed in the workQueue
while(task ! =null|| (task = getTask()) ! =null)
Copy the code
The core of keepAliveTime is the getTask() method
Timed =false if the currently executing thread is a core thread
// Just pull the core code
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
Copy the code
It will execute workqueue.take () to get a thread task from the wait queue because BlockingQueue< Runnable > workQueue is a BlockingQueue and if there are no thread tasks in it that need to be executed it will block until it gets the thread task
workQueue.take();
Copy the code
Key if timed=true execute workqueue.poll (keepAliveTime, timeunit.nanoseconds) : This is where keepAliveTime comes into play
The poll line waits for keepAliveTime to exceed the timeout and returns null
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
Copy the code
GetTask returns NULL when the timeout period is exceeded
while(task ! =null|| (task = getTask()) ! =null)
Copy the code
Push the loop and set
completedAbruptly = false;
Copy the code
The processWorkerExit method is then executed
processWorkerExit(w, completedAbruptly)
Copy the code
ProcessWorkerExit Removes the currently executing worker from the set of worker work classes
workers.remove(w);
Copy the code
And then there’s the logic
if(! completedAbruptly) {AllowCoreThreadTimeOut By default is false. If set to true, corePoolSize timed thread idle time to keepAliveTime is disabled If allowCoreThreadTimeOut is true then timed is also true and that's what's going to go into the poll method and that's what's going to do to timeout off the number of core threads
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0&&! workQueue.isEmpty()) min =1;
// The number of current threads is greater than the number of core threads and the thread is closed
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null.false);
Copy the code
Note the addWorker(null, false) above; completedAbruptly=true and addWorker(null, false); Create an empty worker thread to continue execution