[Multithreading] —— thread pool

1. What is a thread pool and what are the thread pools (creation)

The thread pool is to put multiple thread objects into a container in advance. When using it, you don't need to use new thread but
just go to the pool to get the thread directly, which saves the time of creating sub-threads and improves the code execution efficiency.

Static methods for generating a variety of different thread pools are provided in the java.uti.concurrent./executors class of the JDK

ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(4);
ScheduledExecutorService newScheduledThreadPool =
Executors.newScheduledThreadPool(4);
ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();

Then call their execute method.
The bottom layers of these four thread pools are all implemented by the ThreadPoolExecutor object. The Ali specification manual stipulates that the thread
pool is customized by ThreadPoolExecutor, and the actual development is also the same.

(1) newCachedThreadPool

Create a cacheable thread pool. If the length of the thread pool exceeds the processing needs, idle threads can be recycled flexibly. If
there is no recycling, new threads will be created. The characteristics of this type of thread pool are:
there is almost no limit to the number of worker threads created (in fact, there is a limit, the number is Integer.
MAX_VALUE), so that threads can be added to the thread pool flexibly.
If no task is submitted to the thread pool for a long time, that is, if the worker thread is idle for a specified time (
1 minute by default), the worker thread will be automatically terminated. After termination, if you submit a new task, the thread
pool will recreate a worker thread.
When using CachedThreadPool, you must pay attention to controlling the number of tasks, otherwise, due to a large number of threads
running at the same time, it is likely to cause system paralysis.

(2) newFixedThreadPool

Create a thread pool with the specified number of worker threads. A worker thread is created whenever a task is submitted, and if
the number of worker threads reaches the initial maximum number of the thread pool, the submitted task is stored in the pool queue.
FixedThreadPool is a typical and excellent thread pool, which has the
advantages of improving program efficiency and saving the overhead of creating threads. However, when the thread pool is idle, that is, when there are no runnable tasks in the thread pool
, it will not release the worker thread, and it will also occupy certain system resources.

(3) newSingleThreadExecutor

Create a single-threaded Executor, that is, only create a unique worker thread to execute tasks, and it will only
use the only worker thread to execute tasks, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority)
. If this thread ends abnormally, another one will take its place, guaranteeing sequential execution. The biggest feature of a single worker thread is that it can guarantee that tasks will be executed sequentially, and no multiple threads will be active
at any given time .

(4) newScheduleThreadPool

Create a fixed-length thread pool, and support timing and periodic task execution. For example, delay execution for 3 seconds
.

2. Why use a thread pool?

(1) The work of the thread pool is mainly to control the number of running threads. During the processing, tasks are put into the queue, and then
these tasks are started after the threads are created. If the number of threads exceeds the maximum number, the excess threads wait in line
. Wait for other threads to finish executing, and then take the task out of the queue for execution.

(2) Main features: thread reuse; control the maximum number of concurrency: manage threads.
First: reduce resource consumption. Reduce the cost of thread creation and destruction by reusing created threads
.
Second: Improve response speed. When a task arrives, the task can be executed immediately without waiting for the thread to be created
.
Third: Improve thread manageability. Thread is a scarce resource. If it is created without limit, it will not only consume
system resources, but also reduce the stability of the system. Using thread pool can be used for unified allocation, tuning and monitoring

3. The underlying working principle of the thread pool

insert image description here

  • (1) Step 1: When the thread pool is first created, there are no threads in it, and threads will not be created until a task comes
    . Of course, you can also call the prestartAllCoreThreads() or
    prestartCoreThread() method to pre-create corePoolSize threads
  • (2) Step 2: When calling execute() to submit a task, if the current number of worker threads
    < corePoolSize, directly create a new thread to execute the task
  • (3) Step 3: If the number of worker threads >= corePoolSize at that time, the task will be cached in the task queue
  • (4) Step 4: If the queue is full and the number of worker threads in the thread pool < maximumPoolSize,
    a thread will still be created to execute this task
  • (5) Step 5: If the queue is full and the threads in the thread pool have reached the maximumPoolSize, the
    rejection policy will be executed at this time. The default policy of the JAVA thread pool is AbortPolicy, that is,
    a RejectedExecutionException will be thrown

4. What parameters does the ThreadPoolExecutor object have? How to set the number of core threads and the maximum number of threads? What are the denial strategies?

First of all, we all know that there are 7 parameters:

1) corePoolSize: the number of core threads,

There is a configuration related to it in ThreadPoolExecutor: allowCoreThreadTimeOut (default
is false), when allowCoreThreadTimeOut is false, the core thread will always survive,
even if it is always idle. And when allowCoreThreadTimeOut is true, the core thread
will be recycled when the idle time exceeds keepAliveTime.

(2) maximumPoolSize: maximum number of threads

The maximum number of threads that the thread pool can hold. When the number of threads in the thread pool reaches the maximum, the
rejection strategy will be adopted for adding tasks at this time. The default rejection strategy is to throw a runtime error
(RejectedExecutionException). It is worth mentioning that when the work queue used for initialization is
LinkedBlockingDeque, this value will be invalid.

(3) keepAliveTime: survival time,

When the non-core idle exceeds this time, it will be recycled, and whether the idle core thread is recycled is affected by
allowCoreThreadTimeOut.

(4) unit: the unit of keepAliveTime.

(5) workQueue: task queue

There are three commonly used queues, namely SynchronousQueue, LinkedBlockingDeque (unbounded queue
), and ArrayBlockingQueue (bounded queue).

(6) threadFactory: thread factory,

ThreadFactory is an interface used to create workers. Some properties of the thread can
be customized through the thread factory. By default, a new thread is created directly.

(7) RejectedExecutionHandler: rejection strategy

It is also an interface with only one method. When all the resources in the thread pool have been used and adding a new thread is rejected
, the rejectedExecution method of RejectedExecutionHandler will be called. The default is to throw a
runtime exception.

Thread pool size setting

Thread pool size setting:

  1. Need to analyze the characteristics of the tasks performed by the thread pool: CPU-intensive or IO-intensive
  2. What is the average execution time of each task? The execution time of this task may also be
    related to whether the task processing logic involves network transmission and the underlying system resource dependence.

If it is CPU-intensive, mainly to perform computing tasks, the response time is fast, and the CPU is running all the time. This
kind of task has a high CPU utilization rate, so the configuration of the number of threads should be determined according to the number of CPU cores, and
the number of CPU cores = maximum The number of concurrent execution threads, if the number of CPU cores is added to 4, then the server can execute up to
4 threads at the same time. Too many threads will cause context switching and reduce efficiency. The maximum number of threads in the thread pool
can be configured as the number of cpu cores + 1;

If it is IO-intensive, it mainly performs IO operations, and it takes
a long time to perform IO operations. This is because the CPU is in an idle state, resulting in low CPU utilization. In this case,
the size of the thread pool can be increased. In this case, the waiting time of threads can be combined to make a judgment. The higher the waiting time
, the more threads there are. Generally, you can configure twice the number of cpu cores.

A formula: the optimal number of threads set by the thread pool = ((thread waiting time set by the thread pool + thread
CPU time)/
thread CPU time) * CPU number
The thread cpu time of this formula is the estimated program single thread in the cpu Time to run on (usually use
loadrunner to test a large number of runs to find the average)

rejection policy

  1. AbortPolicy: Throw an exception directly, the default policy;
  2. CallerRunsPolicy: use the caller's thread to execute the task;
  3. DiscardOldestPolicy: Discard the front task in the blocking queue and execute the current task;
  4. DiscardPolicy: Discard tasks directly; of course, you can also implement
    the RejectedExecutionHandler interface according to the application scenario, and customize the saturation policy, such as logging or persistently storing
    tasks that cannot be processed

5. What are the common thread-safe concurrent containers?

CopyOnWriteArrayList, CopyOnWriteArraySet, ConcurrentHashMap
CopyOnWriteArrayList, CopyOnWriteArraySet use copy-on-write to achieve thread safety
ConcurrentHashMap uses segment locks to achieve thread safety


You can also refer to the following articles:
1. Detailed explanation of the 7 parameters of the Java thread pool

2. Thread pool

Guess you like

Origin blog.csdn.net/qq_36256590/article/details/132382788