Using ThreadPoolTaskExecutor

1.The difference between ThreadPoolTaskExecutor and ThreadPoolExecutor

ThreadPoolTaskExecutor is in the spring core package, and ThreadPoolExecutor is the JUC in the JDK.

ThreadPoolTaskExecutor encapsulates ThreadPoolExecutor.

ThreadPoolExecutor structure, ancestor classes all call the Executor interface:

ThreadPoolTaskExecutor structure, ancestor classes all call the Executor interface:

2. Tool class: Executors

Executors is a thread pool tool class, which is equivalent to a factory class, used to create a suitable thread pool and return a thread pool of ExecutorService type. There are following methods:

ExecutorService newFixedThreadPool(): Create a fixed-size thread pool


ExecutorService newCachedThreadPool(): Cache thread pool. The number of thread pools is not fixed and can be automatically changed according to needs.


ExecutorService newSingleThreadExecutor(): Create a single thread pool. There is only one thread in the thread pool

ScheduledExecutorService newScheduledThreadPool(): Create a thread pool that can execute delayed or scheduled tasks
 

3. Which one should be used between ThreadPoolTaskExecutor and ThreadPoolExecutor and Executors?

ThreadPoolTaskExecutor and ThreadPoolExecutor are more flexible than Executors in creating thread pools and can set parameters

ThreadPoolTaskExecutor and ThreadPoolExecutor are recommended, and ThreadPoolTaskExecutor is a package of ThreadPoolExecutor, so the performance is better. ThreadPoolTaskExecutor is recommended .

4. This is the method used by ThreadPoolTaskExecutor to initialize threadPoolExecutor. BlockingQueue is a blocking queue, so we will ignore this first. Since ThreadPoolTaskExecutor is implemented entirely using threadPoolExecutor, we need to know some parameters of this threadPoolExecutor.

ThreadPoolExecutor的:   

public class ThreadPoolTaskExecutor extends ExecutorConfigurationSupport implements SchedulingTaskExecutor {
        private final Object poolSizeMonitor = new Object();
        private int corePoolSize = 1;
        private int maxPoolSize = 2147483647;
        private int keepAliveSeconds = 60;
        private boolean allowCoreThreadTimeOut = false;
        private int queueCapacity = 2147483647;
        private ThreadPoolExecutor threadPoolExecutor;   //这里就用到了ThreadPoolExecutor

ThreadPoolTaskExecutor的:

     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.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }

Parameter Description:

  •     1. corePoolSize: number of core threads (corePoolSize = number of cpu cores * 2 + number of effective disks)
  •     2. queueCapacity: task queue capacity (blocking queue)
  •     3. maxPoolSize: maximum number of threads
  •     4. keepAliveTime: thread idle time
  •     5. allowCoreThreadTimeout: Allow core threads to timeout
  •     6. rejectedExecutionHandler: task rejection handler

        * Two situations will refuse to process tasks:
            - When the number of threads has reached maxPoolSize and the queue is full, new tasks will be rejected
            - When shutdown() is called on the thread pool, it will wait for the tasks in the thread pool to be executed before shutting down. If a task is submitted between calling shutdown() and the actual shutdown of the thread pool, the new task will be rejected
        * and the thread pool will call rejectedExecutionHandler to handle the task. If there is no setting, the default is AbortPolicy, and an exception will
        be
            thrown
            . The main thread directly processes the request
            - DiscardPolicy discards the current task; it will cause the discarded task to be unable to be executed again
            - DiscardOldestPolicy discards the old task; it will cause the discarded task to not be executed again
        * Implement the RejectedExecutionHandler interface and customize the processor

The difference between execute and submit

Submit task type

  •         Both execute and submitsubmitsubmit are methods of the thread pool. execute can only submit tasks of Runnable type.
  •         submit can submit both Runnable and Callable type tasks.

return value

  •         execute() has no return value
  •         Submit has a return value, so you must use submit when you need to return a value.

        Note: The return value of submit is Future<?>, and its generic type can be obtained through get. The Future<?> object.get() method has the function of blocking the current thread (that is, whoever calls the Future<?> object.get() will block, preventing the main thread from getting the return value while the child thread has not yet executed. over)

Thread pool configuration

  import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
    import java.util.concurrent.Executor;
    import java.util.concurrent.ThreadPoolExecutor;
     
    @Configuration
    public class ThreadPoolConfig {
     
        //获取cpu核心数
        private final static int AVAILABLE_PROCESSOR = Runtime.getRuntime().availableProcessors();
     
        /**
         * 通用线程池配置
         */
        @Bean("taskPoolExecutor")
        public Executor taskExecutor() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            //设置核心线程数
            taskExecutor.setCorePoolSize(6);
            //设置最大线程数
            taskExecutor.setMaxPoolSize(6*2);
            //设置队列最大容量
            taskExecutor.setQueueCapacity(12);
            //设置线程空闲时间(秒)
            taskExecutor.setKeepAliveSeconds(60);
            //设置线程名称前缀
            taskExecutor.setThreadNamePrefix("taskPoolExecutor--");
            //调度器shutdown方法被调用时等待当前被调度的任务完成
            taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            //等待时间(秒)
            taskExecutor.setAwaitTerminationSeconds(60);
            //拒绝策略
            taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
            //初始化线程池
            taskExecutor.initialize();
            return taskExecutor;
        }
     
         /**
         * 发送短信线程池
         * @return
         */
        @Bean("sendSmsThreadPool")
        public Executor sendSmsThreadPool() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            //设置线程池参数信息
            taskExecutor.setCorePoolSize(AVAILABLE_PROCESSOR);
            taskExecutor.setMaxPoolSize(AVAILABLE_PROCESSOR + 1);
            taskExecutor.setQueueCapacity(256);
            taskExecutor.setKeepAliveSeconds(20);
            taskExecutor.setThreadNamePrefix("sendSmsThreadPool--");
            taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            taskExecutor.setAwaitTerminationSeconds(60);
            //修改拒绝策略为使用当前线程执行
            taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            //初始化线程池
            taskExecutor.initialize();
            return taskExecutor;
        }
     
        /**
         * 发送邮件线程池
         * @return
         */
        @Bean("sendEmailThreadPool")
        public Executor sendEmailThreadPool() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            //设置线程池参数信息
            taskExecutor.setCorePoolSize(AVAILABLE_PROCESSOR);
            taskExecutor.setMaxPoolSize(AVAILABLE_PROCESSOR + 1);
            taskExecutor.setQueueCapacity(256);
            taskExecutor.setKeepAliveSeconds(20);
            taskExecutor.setThreadNamePrefix("sendEmailThreadPool--");
            taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
            taskExecutor.setAwaitTerminationSeconds(60);
            //修改拒绝策略为使用当前线程执行
            taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            //初始化线程池
            taskExecutor.initialize();
            return taskExecutor;
        }
     
        @Bean(name = "threadPoolTaskExecutor")
        public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
            ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
            executor.setCorePoolSize(5);
            executor.setMaxPoolSize(5);
            executor.setQueueCapacity(10);
            executor.setKeepAliveSeconds(300);
            executor.setThreadNamePrefix("thread-ayokredit"); //线程名称
            executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
            return executor;
        }
           
    }

ThreadPoolTaskExecutor is a class in Spring Framework used to execute asynchronous tasks in applications. It uses the thread pool in Java to manage the execution of tasks. How to use it:

1. Configure ThreadPoolTaskExecutor in the configuration file, including parameters such as thread pool size and queue size.

 import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
     
    import java.util.concurrent.ThreadPoolExecutor;
     
    /**
     * 线程池配置
     */
    @Configuration
    @EnableAsync
    public class ThreadPoolConfig {
     
        // 核心线程数
        private int corePoolSize = 10;
        // 最大线程数
        private int maxPoolSize = 50;
        // 队列最大长度
        private int queueCapacity = 500;
        // 线程池维护线程所允许的空闲时间
        private int keepAliveSeconds = 300;
        // 线程名称
        private String threadNamePrefix = "TASK_EXECUTOR-";
     
        /**
         * 定长线程池
         *
         * @return
         */
        public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
            ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
            taskExecutor.setThreadNamePrefix(threadNamePrefix);
            taskExecutor.setMaxPoolSize(maxPoolSize);
            taskExecutor.setCorePoolSize(corePoolSize);
            taskExecutor.setQueueCapacity(queueCapacity);
            taskExecutor.setKeepAliveSeconds(keepAliveSeconds);
            // 拒绝策略
            taskExecutor.setRejectedExecutionHandler(new         ThreadPoolExecutor.CallerRunsPolicy());
            return taskExecutor;
        }
    }

2. Inject ThreadPoolTaskExecutor into the class that needs to execute asynchronous tasks, and call the execute() method of ThreadPoolTaskExecutor to execute the task.

    @Autowired
    private ThreadPoolTaskExecutor taskExecutor;
     
    public void executeAsyncTask() {
        taskExecutor.execute(() -> {
            // 任务代码
        });
    }

Guess you like

Origin blog.csdn.net/qq_16504067/article/details/131914374