You still don't understand the principle of thread pool? make it up now

1. Why use thread pool

  1. Reduce resource consumption. Reduce the consumption caused by thread creation and destruction by reusing created threads.

  2. Improve responsiveness. When a task arrives, the task can be executed immediately without waiting for the thread to be created.

  3. Improve thread manageability. Threads are scarce resources. If they are created without restrictions, they will not only consume system resources, but also reduce the stability of the system. Using thread pools can be used for unified allocation, tuning, and monitoring.

2. Detailed explanation of ThreadPoolExecutor thread pool class parameters

parameter illustrate
corePoolSize The number of core threads, the minimum number of thread pool maintenance threads
maximumPoolSize The maximum number of thread pool maintenance threads
keepAliveTime The longest idle time of other threads in the thread pool except core threads. Idle threads that exceed this time will be destroyed.
unit The unit of keepAliveTime, several static properties in TimeUnit: NANOSECONDS, MICROSECONDS, MILLISECONDS, SECONDS
workQueue The task buffer queue used by the thread pool
threadFactory Thread factory, used to create threads, generally use the default
handler Thread pool's processing strategy for rejected tasks

When the thread pool task cannot be processed (when it is considered that it cannot be processed), it can be processed through the strategy specified by the handler. ThreadPoolExecutor provides four strategies:

  1. ThreadPoolExecutor.AbortPolicy: Aborts the task and throws a RejectedExecutionException exception; it is also the default processing method.
  2. ThreadPoolExecutor.DiscardPolicy: Discards tasks, but does not throw exceptions.
  3. ThreadPoolExecutor.DiscardOldestPolicy: Discard the task at the front of the queue and retry the task (repeat this process)
  4. ThreadPoolExecutor.CallerRunsPolicy: The task is handled by the calling thread

The processing method can be customized by implementing the RejectedExecutionHandler interface.

3. Thread pool task execution

1. Add an execution task

  • submit() This method returns a Future object, which can execute the thread with the return value; or execute the thread that can be canceled at any time. The get() method of the Future object gets the return value. cancel(true/false) of the Future object cancels the task, and returns false if it has not started or completed. The parameter indicates whether to interrupt the executing thread.
  • execute() has no return value.

2. Thread pool task submission process

2.1. If the number of threads in the thread pool is less than corePoolSize at this time, even if the threads in the thread pool are all idle, new threads should be created to process the added tasks.

2.2. If the number in the thread pool is equal to corePoolSize at this time, but the buffer queue workQueue is not full, then the task is put into the buffer queue.

2.3. If the number in the thread pool is greater than or equal to corePoolSize at this time, the buffer queue workQueue is full, and the number in the thread pool is less than the maximumPoolSize, create a new thread to process the added task.

2.4. If the number in the thread pool is greater than corePoolSize at this time, the buffer queue workQueue is full, and the number in the thread pool is equal to the maximumPoolSize, then the task is processed by the strategy specified by the handler.

2.5. When the number of threads in the thread pool is greater than corePoolSize, if a thread idle time exceeds keepAliveTime, the thread will be terminated. In this way, the thread pool can dynamically adjust the number of threads in the pool.

The summary is: the priority of processing task judgment is core thread corePoolSize, task queue workQueue, maximum thread maximumPoolSize, if all three are full, use handler to process rejected tasks.

Notice:

  1. When the workQueue uses an unbounded queue, the maximumPoolSize parameter becomes meaningless, such as new LinkedBlockingQueue(), or new ArrayBlockingQueue(Integer.MAX_VALUE);
  2. When using the SynchronousQueue queue, because the queue has no capacity, the task will not be queued. If there is no idle thread in the thread pool, a new thread will be created immediately to receive the task. The maximumPoolSize should be set larger.
  3. keepAliveTime has no effect when the number of core threads and maximum threads are equal.

3. The thread pool is closed

3.1. shutdown() does not accept new tasks, it will process added tasks 3.2. shutdownNow() does not accept new tasks, does not process added tasks, and interrupts the tasks being processed

4. Introduction to common queues

4.1. ArrayBlockingQueue: This is a fixed-capacity bounded blocking queue implemented by an array.

4.2. SynchronousQueue: No capacity, no data can be cached; each put must wait for a take; when offer(), if there is no other thread in poll() or take(), it returns false.

4.3. LinkedBlockingQueue: This is a default unbounded blocking queue implemented by a singly linked list. LinkedBlockingQueue provides an optional bounded constructor, and when no capacity is specified, the capacity defaults to Integer.MAX_VALUE.

Queue operations:

method illustrate
add Increment an index; if the queue is full, throw an exception
remove Removes and returns the element at the head of the queue; if the queue is empty, throws an exception
offer Adds an element and returns true; if the queue is full, returns false
poll Removes and returns the element at the head of the queue; returns null if the queue is empty
put add an element; block if queue is full
take Remove and return the element at the head of the queue; block if the queue is empty
element Returns the element at the head of the queue; if the queue is empty, throws an exception
peek Returns the element at the head of the queue; returns null if the queue is empty

5. Executors thread factory class

1. Executors.newCachedThreadPool(); Description: Create a cacheable thread pool. If the length of the thread pool exceeds the processing needs, the idle threads can be flexibly recovered. If there is no recovery, a new thread will be created. Internal implementation: new ThreadPoolExecutor(0, Integer. MAX_VALUE,60L,TimeUnit.SECONDS,new SynchronousQueue<runnable>());</runnable>

2. Executors.newFixedThreadPool(int); Description: Create a fixed-length thread pool, which can control the maximum number of concurrent threads. Exceeded threads will wait in the queue. Internal implementation: new ThreadPoolExecutor(nThreads, nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<runnable>());</runnable>

3. Executors.newSingleThreadExecutor(); Description: Create a single-threaded thread pool, which only uses a single worker thread to execute tasks to ensure that all tasks are executed in order. Internal implementation: new ThreadPoolExecutor(1,1,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<runnable>())</runnable>

4. Executors.newScheduledThreadPool(int); Description: Create a fixed-length thread pool to support timing and periodic task execution. Internal implementation: new ScheduledThreadPoolExecutor(corePoolSize)

[Attachment] Specifications for the use of thread pools in the Alibaba Java Development Manual

  1. [Mandatory] When creating a thread or thread pool, please specify a meaningful thread name, which is convenient for backtracking when an error occurs. Positive example:
public class TimerTaskThread extends Thread {
    public TimerTaskThread(){
        super.setName("TimerTaskThread"); 
        ...
    }
}
  1. [Mandatory] Thread resources must be provided by the thread pool. Explicit creation of threads in the application is not allowed. Description: The advantage of using a thread pool is to reduce the time spent on creating and destroying threads and the overhead of system resources, and solve the problem of insufficient resources. If the thread pool is not used, it may cause the system to create a large number of threads of the same type, which may cause the problem of running out of memory or "excessive switching".

  2. [Mandatory] Executors are not allowed to create thread pools, but ThreadPoolExecutors are used. This way of processing allows the writers to be more specific about the running rules of thread pools and avoid the risk of resource exhaustion.

Note: The disadvantages of the thread pool object returned by Executors are as follows: 1) FixedThreadPool and SingleThreadPool: The allowed request queue length is Integer.MAX_VALUE, which may accumulate a large number of requests, resulting in OOM. 2) CachedThreadPool and ScheduledThreadPool: The allowed number of threads to be created is Integer.MAX_VALUE, which may create a large number of threads, resulting in OOM.

6. Summary

ThreadPoolExecutor defines different types of thread pools through several core parameters, which are suitable for different usage scenarios; among them, when the task is submitted, it will judge corePoolSize, workQueque, and maximumPoolSize in turn, and different states will be processed differently. The water in the technical field is too deep. If it is not used daily, some knowledge points will be almost forgotten after a basic period of time. Therefore, it is necessary to review and summarize in stages to consolidate your technical foundation.

Pay attention, don't get lost, this is a public account that programmers want to pay attention to

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324130726&siteId=291194637