Thread Pool in JDK1.8 and JDK1.8
The above code has been used, and is frequently asked during interviews, but has never been used in depth. I don't know what the thread pool is like. Today, let's look at the source code to find out exactly what it is.
The main control of the thread pool is ctl, which is an atomic integer and contains two conceptual fields:
- WorkerCount: Number of valid threads
- RunState: the State of the thread pool.
To include these two fields in an integer value, we limit workerCount to 1 minus the 29 power of 2
RunState values are as follows:
- RUNNING: receives new tasks and processes tasks in the queue.
- SHUTDOWN: Do not accept new tasks. Continue to process tasks in the queue.
- STOP: Do not accept new tasks, do not process tasks in the queue, and interrupt the tasks being processed
- TIDYING: all tasks are finished, and workerCount is 0. You can call the terminated () method to convert the status.
- TERMINATED: The terminated () method has been completed.
The conversion between States is as follows:
RUNNING-> SHUTDOWN
Call the shutdown () method or call the finalize () method implicitly.
(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
Therefore, COUNT_BITS = 29
High 3-bit storage runState
Next, let's look at the most complex constructor.
Parameter Details
- CorePoolSize: Number of threads in the pool (PS: even if they are idle)
- MaximumPoolSize: Maximum number of threads allowed in the pool
- KeepAliveTime: when the number of threads exceeds the number of core threads, the maximum lifetime of the thread is exceeded.
- Unit: the unit of keepAliveTime.
- WorkQueue: Maintain the queue of tasks to be processed
- ThreadFactory: the factory for creating threads
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, put it in the work queue
3. If the work queue is full (PS: workQueue. offer (command) returns false), a new thread is created.
4. If the number of threads has reached the maximum number of threads, reject (command)
In the previous execute method, the addWork () method is called in three places.
First, if the number of valid threads is less than the number of core threads, call it. the boundary of the number of threads is the number of core threads.
Second, if the number of valid threads exceeds the number of core threads and new tasks are put in the queue, and the number of valid threads is 0, a new thread is created.
Third, if the number of valid threads exceeds the number of core threads and the queue is full, and the number of valid threads is smaller than the maximum number of threads,
The current valid threads are all in works, and the Worker object is put in works. Next, let's look at Worker.
In the previous step, the start () method of the thread executes the run () method when the thread is running, while the Worker inherits Runnable and re-runs () method, run () the method also calls the external runWorker () method. Therefore, the runWorker () method is called when the newly created thread in the thread pool is running.
The runWorker () method cyclically fetches a task from the queue and executes it. That is to say, when all the threads in the pool are created, if a new task is uploaded, the new task is executed first, and then the task is retrieved from the queue cyclically and executed
Next, let's look at the differences between several common thread pools in Executors.
We can see that
NewSingleThreadExecutor: the number of core threads and the maximum number of threads are both 1, and the queue is queue blockingqueue.
NewFixedThreadPool: the number of core threads is equal to the maximum number of threads. The idle thread survival time exceeds the number of core threads is 0, and the queue is LinkedBlockingQueue.
NewCachedThreadPool: the number of core threads is 0, the maximum number of threads is Integer. MAX_VALUE, the idle thread survival time is 1 min, and the queue is SynchronousQueue.