SpringBoot uses thread pools

/** * Thread pool configuration and initialization */
@Data
@ConfigurationProperties("executor")
@Configuration
public class ThreadExecutorPool {
    private Integer corePoolSize;
    private Integer maxPoolSize;
    private Integer queueCapacity;
    private Integer keepAliveSeconds;
    private String threadNamePrefix;

    @Bean("taskAsyncPool")
    public ThreadPoolTaskExecutor taskAsyncPool(a) {
        ThreadPoolTaskExecutor executor = newThreadPoolTaskExecutor(); executor.setCorePoolSize(corePoolSize); executor.setMaxPoolSize(maxPoolSize); executor.setQueueCapacity(queueCapacity); executor.setKeepAliveSeconds(keepAliveSeconds); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        executor.setThreadNamePrefix(getThreadNamePrefix());
        executor.initialize();
        returnexecutor; }}Copy the code

The configuration file

executor:
    corePoolSize: 5
    maxPoolSize: 10
    queueCapacity: 20
    keepAliveSeconds: 60
    threadNamePrefix: XCExecutor-
Copy the code
  • Added to the SpringBoot boot class@EnableAsyncannotations
  • Then add methods that require multithreaded execution@Async(value = "taskAsyncPool")Annotations can be

Thread pooling is a form of multithreaded processing in which tasks are added to a queue and then automatically started when a thread is created. Threads can be used in one of two ways: by inheriting the Thread class, or by implementing the Runnable interface. Thread implements the Runnable interface. Both methods are destroyed by the VM after receiving. If the number of threads is large, frequent creation and destruction can be a huge waste of time and efficiency, as well as a waste of memory. In order to reduce the number of threads created and destroyed, so that each thread can be used more than once, you can adjust the number of threads executed according to the system conditions, to prevent excessive memory and time consumption. A thread pool consists of the following four basic parts:

  • Thread pool Manager (ThreadPool) : Used to create and manage thread pools, including destroying them and adding new tasks
  • Worker thread (PoolWorker) : a thread in a thread pool that is in a waiting state when there is no work to do
  • Task Interface (Task) : the interface that each task must implement for the worker thread to schedule the execution of the task. It mainly defines the entry of the task, the finishing work after the task is executed, and the configuration of the task execution, etc
  • Task queue (taskQueue) : Used to store unprocessed tasks. A buffer mechanism.

The characteristics of

  • Thread the reuse
  • Controls the maximum number of concurrent requests
  • Management of thread

advantages

  • Reduced resource consumption. The reuse mechanism reduces the cost of thread creation and destruction
  • Improve response speed. When a task comes, it can be executed immediately without waiting for the time to create the thread
  • Improved thread management. If created without limit, not only consume system resources, but also reduce system stability, using thread pool can be unified allocation, tuning, and control

The top layer of the thread pool interface is Executor. This interface defines the core method execute(Runnable Command), which is finally implemented by the ThreadPoolExecutor class and used to pass in tasks. ThreadPoolExecutor is the core thread pool class. This constructor looks like this:

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }
Copy the code
  • corePoolSize: The size of the core thread pool. If the core thread pool has free space, the new task will be executed by a new thread in the core thread pool. After execution, the thread will not be destroyed, and the thread will be put into the cache queue waiting to be executed again.
  • maximumPoolSize: A thread pool can create the maximum number of threads. If both the core thread pool and the cache queue are full, new tasks come in and new threads are created to execute them. But the quantity cannot exceedmaximunPoolSize, whether the side will adopt the task rejection strategy, which will be analyzed in detail below.
  • keepAliveTime: Maximum time that a non-core thread can be idle, after which the thread terminates. By default, this parameter takes effect only if the number of threads exceeds the core thread pool size. It does not work as long as the number of threads does not exceed the core thread size.
  • unit: Time units, andkeepAliveTimeUse together.
  • workQueue: Cache queue, used to store tasks waiting to be executed.
  • threadFactory: thread factory, used to create threads, generally with three selection strategies.
  • ArrayBlockingQueue
  • LinkedBlockingQueue
  • SynchronousQueue
  • handler: reject processing policy. If the number of threads exceeds the maximum number, the reject processing policy is adopted
  • ThreadPoolExecutor.AbortPolicy: Discards the task and throws itRejectedExecutionExceptionThe exception.
  • ThreadPoolExecutor.DiscardPolicy: Also drops the task, but does not throw an exception.
  • ThreadPoolExecutor.DiscardOldestPolicy: Discards the task at the top of the queue, then retry the task (repeat the process)
  • ThreadPoolExecutor.CallerRunsPolicy: The calling thread handles the task
  • implementationRejectedExecutionHandlerInterface, you can also customize the processor.