JDK1. Thread pool in 8
The above code has been used all the time. I'm often asked during the interview, but I've never studied it deeply. I don't know what's going on with the thread pool. Today, let's look at the source code and find out what's going on
The main control state of thread pool is CTL, which is an atomic integer, which contains two concept fields:
In order to include these two fields in an integer value, we limit the workercount to the 29th power of 2 minus 1
There are several runstate values:
The transition between States is as follows:
RUNNING -> SHUTDOWN
Call the shutdown () method, or implicitly call the finalize () method
(RUNNING or SHUTDOWN) -> STOP
Call the shoutdownnow() method
SHUTDOWN -> TIDYING
When the queue and pool are empty
STOP -> TIDYING
When the pool is empty
TIDYING -> TERMINATED
When the terminated () method call is complete
Integer. SIZE=31
Integer. SIZE - 3 = 29
So, count_ BITS = 29
The upper 3 bits store runstate
Next, let's look at the most complex construction method
Detailed explanation of parameters
1. If the number of running threads is less than the number of core threads, create a new thread to run the task
2. If the work queue is not full, it is placed in the work queue
3. If the work queue is full (PS: workqueue. Offer (command) returns false), create a new thread
4. If the number of threads has reached the maximum number of threads, reject (command)
In the previous execute method, addwork () method was called in 3 places
First, if the current number of effective threads is less than the number of core threads, it will be called. At this time, the boundary of the number of threads is the number of core threads
Second, if the current number of effective threads exceeds the number of core threads and the new task is put in the queue, and the number of effective threads is 0, a new thread is created
Third, if the current number of effective threads exceeds the number of core threads, the queue is full, and the number of effective threads is less than the maximum number of threads, call to create a new thread,
The current valid threads are all in works, and the worker object is placed in works. Next, let's look at worker
In the previous step, the thread's start () method executes the run () method when the thread runs, and the worker inherits the runnable and rerun () method. The run () method calls the external runworker () method. Therefore, the runworker () method is called when the thread newly created in the thread pool runs
The runworker () method circularly takes the task from the queue and executes it. That is, all threads in the pool are created. If a new task is passed in, the new task will be executed first, and then the task will be taken out of the queue and executed circularly
Next, let's look at the differences between several common thread pools in executors
Can see
Newsinglethreadexecution: the number of core threads and the maximum number of threads are 1, and the queue is linkedblockingqueue
Newfixedthreadpool: the number of core threads is equal to the maximum number of threads. The lifetime of idle threads exceeding the number of core threads is 0, and the queue is linkedblockingqueue
Newcachedthreadpool: the number of core threads is 0, and the maximum number of threads is integer MAX_ Value, the idle thread lifetime is 1min, and the queue is synchronous queue
Examples
Chestnut 1
Suppose that the fixed thread of newfixedthreadpool is 2, all the maximum threads and core threads are 2, and its work queue uses linkedblockingqueue.
When the first task is submitted, create a new thread and execute the task. At this time, there is one thread in the thread pool;
When the second task is submitted, create a new thread and execute the task. At this time, there are two threads in the thread pool;
When the third task is submitted, it is put into the work queue, and then the two threads in the thread pool poll the queue for processing
When the nth task is submitted, it is still put into the work queue
Chestnut 2
Suppose newcachedthreadpool. It should be noted that its work queue is synchronous queue. The characteristic of this queue is that when one thread puts elements into the queue, another thread must take elements out of the queue at the same time, otherwise it cannot put them in
When the first task is submitted, the number of threads in the thread pool is 0, so create a new thread and execute the task. At this time, there is 1 thread in the thread pool;
When the second task is submitted, because it cannot be put into the queue, another thread is created. At this time, there are two threads in the thread pool;
When the third task is submitted, if one of the first two threads has finished processing, all can be put into the work queue because it is fetched from the queue in a loop