How the thread pool works has been unclear to me, today to comb the source code.

Thread pool tasks submit and run

Looking directly at the results, the main process is as follows:

Execute commits the task — > create Worker(set thead, firstTask) — >worker.thread.start() — > worker.run() — > runWorker(Worker) — >work Er. FirstTask. The run ();

If you don’t understand the above process, you can look at the next step to analyze how they came to **. 支那

Thread pool basics

You should know the basics of thread pooling, but here are a few things to start reading the source code for. Here are the 7 most important parameters for creating a thread pool:

CorePoolSize: number of core threads in the thread pool;

MaximumPoolSize: The maximum number of threads that can be created by the thread pool;

KeepAliveTime: The maximum idle lifetime of the portion of the thread pool larger than corePoolSize.

Unit: Unit of survival time;

WorkQueue: A blocking queue that holds tasks waiting to be executed. When a task is submitted again while all threads in the thread pool are running, the task is stored in the blocking queue.

ThreadFactory: A factory for creating threads, DefaultThreadFactory class by default;

Handler: thread saturation strategy, if all the thread pool threads are on a mission, and full of waiting queue, the specified processing method, the default for ThreadPoolExecutor. AbortPolicy.

Execute source code step

The execution steps of execute method source code are summarized as follows:

The execute method can be divided into three steps:

First, if the number of current worker threads is smaller than the core thread, the addWorker(command, true) method is called to create the core thread to execute the task.

Second, if the current thread is larger than the number of core threads, it will judge whether the wait queue is full. If not, it will add tasks to the wait queue. If the number of worker threads is 0, it will call addWorker(null, false) method to create non-core threads and pull tasks from the wait queue for execution.

Finally, if the queue is full, the addWorker(Command, false) method is called to create a non-core thread to execute the task. If the creation fails, the task is rejected.

In simple terms, the core thread comes first, the queue comes second, and the non-core thread comes last.

AddWorker method

As you can see, the key to execute is the addWorker method, which takes two arguments:

The first argument is the task to execute. If null, the task is pulled from the wait queue.

The second parameter indicates whether the core thread is used to control the flow of the addWorker method.

The main process of the addWorker method is as follows:

There is a step in the process to verify that the number of threads is greater than the number of core threads or the maximum number of threads. If core is passed as true, the number of running threads cannot be greater than the number of core threads. If it is false, the number of current threads cannot be greater than the maximum number of threads.

AddWorker has only two functions: increase the number of Worker threads, create a Worker, and add it to the Worker thread collection.

The Worker class

The Worker class is the class that performs tasks in the thread pool. The main source code and explanation are shown below:

Therefore, Worker itself is a Runnable with two attributes, thead and firstTask. Then we can sort out the overall operation process:

Execute — > create Worker(set thead, firstTask) — >worker.thread.start() — > actually call worker.run() — > thread pool runWorker(Worker) — >worker.f Irsttask.run ()(pulls one from the wait queue if firstTask is null).

After a long circle, the run method of the originally passed task is called. However, by waiting for queues, workers and threads in workers can be reused, changing only firstTask;

conclusion

The function of execute in thread pool is to put the task into the waiting queue or create a new worker and put the task into the worker’s firstTask, and finally execute the thread in the worker.

The thread start method in Worker executes the Worker’s run method;

The Worker’s run method calls the thread pool’s runWorker method;

The runWorker method calls the run method of worker’s firstTask to achieve the purpose.

The advantage is that you can reuse workers and threads in workers, which is also an advantage of thread pools.

Java programmer daily study notes, such as understanding the wrong welcome to exchange discussion!