Thread pool basics
1. Thread pool Executors: The ThreadPoolExecutor class implements the Executor interface, so that any Runnable object can be scheduled by the ThreadPoolExecutor thread pool through this interface. Common thread pool types
-
public static ExecutorService newFixedThreadPool(int nThreads) Copy the code
Returns a thread pool with a fixed number of threads. The number of threads is always the same. Execute immediately when there are idle threads. If not, the new thread exists in a task queue temporarily. When the thread is idle, it starts to process tasks in the task queue.
-
public static ExecutorService newSingleThreadExecutor(a) Copy the code
Returns a thread pool with only one thread. The new line is stored in the task queue. When the thread is idle, the task in the task queue is processed.
-
public static ExecutorService newCachedThreadPool(a) Copy the code
Returns a thread pool that can adjust the number of threads as needed. The number of processes in a thread is uncertain, but if there are idle threads that can be reused, that thread will be used first. If all threads are working and a new task is submitted, a new thread is created to execute the task. All threads will return to the thread pool for feeding after the current task is complete.
-
public static ScheduledExecutorService newSingleThreadScheduldExecutor(a) Copy the code
Return a ScheduledExecutorService object with a thread pool size of 1. Execute after a fixed delay, or execute a task periodically
-
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) Copy the code
Same as above, but you can specify the number of threads.
Internal implementation of the core thread pool
For several thread pools in the core, the internal implementation uses the ThreadPoolExecutor implementation.
-
public static ExecutorService newFixedThreaPool(int nThreads) { return new ThreadPoolExecutor(nThreads,nThreads, 0L,TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); } Copy the code
-
public static ExecutorService newSingleThreadExecutor(a) { return new ThreadPoolExecutor(1.1.0L,TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>()); } Copy the code
-
public static ExecutorService newCachedThreadPool(a) { return new ThreadPoolExecutor(0,Integer.MAX_VALUE, 60L,TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } Copy the code
Take a look at the most important constructor of ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long KeepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
Copy the code
The parameters of the function are as follows:
corePoolSize
: Number of threads in the thread pool.maximumPoolSize
: Maximum number of threads in the thread pool.keepAliveTime
: When the number of thread pools exceedscorePoolSize
, the lifetime of the excess idle threads.unit
:keepAliveTime
Of the unit.workQueue
: task queue, tasks that have been submitted but not yet executed.threadFactory
: thread factory, used to create threads, usually using the default.handler
: Rejection policy. How to say no to tasks when there are too many to handle.
In the above parameters, the rest is easy to understand, but the workQueue and handler need to be mentioned.
workQueue
Task queue explanation
A workQueue is a queue of submitted tasks that have not yet been executed. It is an object of the BlockingQueue interface that exists only for Runnable objects. The following blockingQueues can be used in the constructor of ThreadPoolExecutor, depending on the queue functionality:
- Queue for direct submission
SynchronousQueue
:SychronousQueue
Is a special oneBlockingQueue
.SychronousQueue
Without capacity, each insert waits for a corresponding delete, and conversely, each delete waits for a corresponding insert. If you are usingSychronousQueue
If there are no idle threads, try to create a new thread. If the number of processes has reached the maximum, the policy will be rejected. Therefore, useSychronousQueue
It’s usually very largemaximumcorePoolSize
Otherwise, it is easy to implement a rejection strategy. - A bounded task queue
ArrayBlockingQueue
Features:If a new task needs to be executed, if the actual thread pool is less thancorePoolSize
, the new thread will be created first. If more thancorePoolSize
, the new task is added to the waiting queue. If the wait queue is full and unable to join, the bus maturity is not greater thanmaximumPoolSize
Create a new thread to execute the task. If yes, the denial policy is executed. - Unbounded queue of tasks
LinkedBlockingQueue
Features:If a new task needs to be executed, if the actual thread pool is less thancorePoolSize
, the new thread will be created first. If more thancorePoolSize
To enter the waiting queue. - Priority task queue
PriorityBlockingQueue
: Tasks can be executed according to their priorities.
handler
Rejection Strategy Explanation
The built-in rejection policies of JKD are implemented through the RejectedExecutionHandler interface, as follows:
AbortPolicy
Strategy: Directly throw exceptions to prevent the system from working properly;CallerRunsPolicy
Policy: Run the currently discarded task directly in the caller thread as long as the thread is not closed.Warning: Performance may deteriorate sharplyDiscardOledstPolicy
Strategy: Discard one of the oldest requests and try to submit the current task again.DiscardPolicy
Policy: Discard unprocessed requests, do not process them, and do not prompt them.