An inherited implementation structure for ThreadPoolExecutor
Status of the thread pool
ThreadPoolExecutor uses the high three bits of int to indicate the state of the thread and the low 29 bits to indicate the number of threads.
The confidence is stored in a CTL atomic variable to combine the thread state and the number of threads, and to perform a CAS operation to complete the assignment of both.
Thread pool constructors and parameters
- CoorPoolSize: indicates the number of core threads
- MaxinumPoolSize: indicates the maximum number of threads
- KeepAliveTime: Indicates the duration of the emergency thread
- Unit: time unit for the previous parameter
- WorkQueue: blocking queue
- ThreadFactory: a threadFactory
- Handler: rejects the policy
Thread pool workflow:
-
The thread pool does not have threads at first. When a task is submitted, the pool creates a thread to execute the task
-
When multiple tasks are submitted, if the current thread is in a working state and cannot process the task in a timely manner, the thread pool creates additional threads to execute the task
-
When the number of threads in the thread pool reaches coorPoolSize, when a new task is submitted, if all threads are currently working, the thread pool adds the new task to the workQueue blocking queue
-
If more and more tasks are submitted to the blocking queue, if the blocking queue is bounded, if new tasks are submitted when the blocking queue is full, then an emergency thread will be created to execute the task. Maximum number of emergency threads maxinumPoolSize minus the number of core threads coorPoolSize.
-
When all the emergency threads have been created and the task queue is full, a reject policy is executed. The JDK provides four or four implementations of the reject policy, each of which has different effects:
- AbortPolicy: let the caller throws RejectedExecutorException anomalies
- CallerRunsPolicy: Lets the caller run the task
- DiscardPolicy: Abort the task
- DisscardOldestPolicy: Discards the earliest task added to the queue and replaces it with this task
-
When the peak has passed, the emergency thread is terminated if it has not worked for a period of time, which is controlled by keepAliveTime and Unit
Thread pool worker factory
The JDK Executors class provides various thread pool factory methods. Each method returns a thread pool with different characteristics by calling the thread pool constructor with different parameter values.
1. newFixedThreadPool
For a thread pool with a fixed number of threads, we can see that when the constructor passes a parameter, the maximum number of threads is equal to the number of core threads, meaning that no emergency thread will be created, so the emergency thread lifetime is also 0, and the blocking queue is also unbounded.
The characteristics of
- There is no emergency thread
- Blocking queues are unbounded queues that can keep adding tasks to them
It is suitable for tasks with known task quantity and long execution time
2.newCachedThreadPool
In the buffer pool, we can see that the sum of the thread pool is 0, and the number of emergency threads is the maximum value of Integer. The survival time of emergency threads is 60 seconds. The blocking queue uses a blocking queue with no capacity.
Features:
- There is no number of core threads, all threads are emergency threads, and the idle lifetime of emergency threads is 60 seconds
- SynchronousQueue is used as a blocking queue, which has no capacity and can only be put into a task when it is fetched by a thread
This method applies to scenarios where the tasks are intensive but the execution time of a single task is short.
3.newSingleThreadPool
Single threaded thread pool, no emergency thread, blocking queue is unbounded queue
4.newScheduledThreadPool
Task scheduling thread pool, which can execute tasks regularly or periodically
Scheduled task execution:
Periodically executing tasks:
Note: If the time taken for the last task is longer than the interval period, the next task will be executed immediately after the last task is completed
The characteristics of
- Using the decorator pattern, which exposes specific methods, prevents some core methods from being exposed and thus breaking a single thread.
The difference between a single-threaded thread pool and creating your own thread
A self-created thread terminates execution with no remedy in the event of an exception, whereas a single-threaded thread pool that fails during execution creates a new thread to ensure the execution of subsequent tasks.
Submit a task
There are several ways to submit a task defined in the thread pool:
Closing the thread pool
shutdown()
This method changes the state of the thread pool to SHUTDOWN, and no new tasks are accepted. However, the submitted tasks are completed. Calling this method does not block thread execution.
shutdownNow()
When the thread pool state changes to STOP, the task being executed is interrupted with interrupt, no new tasks are accepted, and tasks in the queue are returned to block.