Spring boot中的线程池-ThreadPoolTaskExecutor

一、jdk的阻塞队列:

二、Spring boot工程的有哪些阻塞队列呢?

1、默认注入的ThreadPoolTaskExecutor

视频解说:

线程池篇-springboot项目中的service层里简单注入ThreadPoolTaskExecutor并且使用_哔哩哔哩_bilibili

程序代码:ThreadPoolDemo/ThreadPool00 · xin麒/XinQiUtilsOrDemo - 码云 - 开源中国 (gitee.com)

简单在service层注入的话是这样的:

java 复制代码
@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;

同时在这里使用这个线程池:

java 复制代码
@Override
public Object springbootThreadPool(Long count) {
    try {
        threadPoolTaskExecutor.execute(() -> {
            try {
                Thread.sleep(1000 * 1);
                log.debug("v me 50");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
    return "nice";
}

以debug方式启动项目来查看一下,发现这里默认使用的阻塞队列是:

2、自定义ThreadPoolTaskExecutor

视频解说:

【2】https://www.bilibili.com/video/BV1Qu4y1X7zk

【3】https://www.bilibili.com/video/BV1Cu4y1i7Ae

程序代码:

https://gitee.com/flowers-bloom-is-the-sea/XinQiUtilsOrDemo/tree/master/ThreadPoolDemo/ThreadPool0

验证方式1-通过启动springboot工程,通过debug形式查看:

java 复制代码
@Bean("xinTaskExecutor")
public Executor xinTaskExecutor() {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    //设置线程池参数信息
    taskExecutor.setCorePoolSize(10);
    taskExecutor.setMaxPoolSize(50);
    taskExecutor.setQueueCapacity(0);
    taskExecutor.setKeepAliveSeconds(60);
    taskExecutor.setThreadNamePrefix("xinTaskExecutor--");
    taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
    taskExecutor.setAwaitTerminationSeconds(60);

    //修改拒绝策略为使用当前线程执行
    taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
    //初始化线程池
    taskExecutor.initialize();
    return taskExecutor;
}

验证方式2-main方法创建并初始化:

通过debug形式查看

①查看initialize方法就可以了

java 复制代码
public static void main(String[] args) {
    ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
    //设置线程池参数信息
    taskExecutor.setCorePoolSize(10);
    taskExecutor.setMaxPoolSize(50);
    taskExecutor.setQueueCapacity(0);
    taskExecutor.setKeepAliveSeconds(60);
    taskExecutor.setThreadNamePrefix("myExecutor--");
    taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
    taskExecutor.setAwaitTerminationSeconds(10);

    //修改拒绝策略为使用当前线程执行
    taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
    //初始化线程池
    taskExecutor.initialize();
}

②可以看到ExecutorConfigurationSupport类里面有这个方法

java 复制代码
public void initialize() {
   if (logger.isInfoEnabled()) {
      logger.info("Initializing ExecutorService" + (this.beanName != null ? " '" + this.beanName + "'" : ""));
   }
   if (!this.threadNamePrefixSet && this.beanName != null) {
      setThreadNamePrefix(this.beanName + "-");
   }
   this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler);
}

直接看this.executor = initializeExecutor(this.threadFactory, this.rejectedExecutionHandler)

③来到org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor

java 复制代码
@Override
protected ExecutorService initializeExecutor(
      ThreadFactory threadFactory, RejectedExecutionHandler rejectedExecutionHandler) {

   BlockingQueue<Runnable> queue = createQueue(this.queueCapacity);

   ThreadPoolExecutor executor;
   if (this.taskDecorator != null) {
      executor = new ThreadPoolExecutor(
            this.corePoolSize, this.maxPoolSize, this.keepAliveSeconds, TimeUnit.SECONDS,
            queue, threadFactory, rejectedExecutionHandler) {
         @Override
         public void execute(Runnable command) {
            Runnable decorated = taskDecorator.decorate(command);
            if (decorated != command) {
               decoratedTaskMap.put(decorated, command);
            }
            super.execute(decorated);
         }
      };
   }
   else {
      executor = new ThreadPoolExecutor(
            this.corePoolSize, this.maxPoolSize, this.keepAliveSeconds, TimeUnit.SECONDS,
            queue, threadFactory, rejectedExecutionHandler);

   }

   if (this.allowCoreThreadTimeOut) {
      executor.allowCoreThreadTimeOut(true);
   }

   this.threadPoolExecutor = executor;
   return executor;
}

直接看createQueue(this.queueCapacity)即可

org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor#createQueue

可以看到要么new LinkedBlockingQueue<>(queueCapacity)要么就new SynchronousQueue<>()

java 复制代码
protected BlockingQueue<Runnable> createQueue(int queueCapacity) {
   if (queueCapacity > 0) {
      return new LinkedBlockingQueue<>(queueCapacity);
   }
   else {
      return new SynchronousQueue<>();
   }
}

那么有没有其他阻塞队列可选呢?这个我就没详细去看了,可以自己尝试下找一下有没有其他方式可以的,难道说重写在里面的方法吗?可行性有待验证。如果创建一个继承了org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor类,且重写了createQueue方法的话那么可以考虑下。就这样吧。

三、和jdk的线程池的区别

1、感觉没什么区别,因为ThreadPoolTaskExecutor内使用的线程池本来就是成员变量中的

java 复制代码
@Nullable
private ThreadPoolExecutor threadPoolExecutor;

2、springboot的项目里可以通过注解方式来执行方法

只不过指定使用哪个线程池来执行要异步执行方法的内容。

https://www.bilibili.com/video/BV1A14y1B78x/

如果是默认的注解来执行内容则可能有其他问题:

https://www.bilibili.com/video/BV1Gu4y1q7TY

但是可以通过注解指定使用哪个线程池:

https://www.bilibili.com/video/BV1e44y1c7uE

相关推荐
Darkdreams15 分钟前
SpringBoot项目集成ONLYOFFICE
java·spring boot·后端
bropro34 分钟前
【Spring Boot】Spring AOP中的环绕通知
spring boot·后端·spring
lhbian34 分钟前
【Spring Cloud Alibaba】基于Spring Boot 3.x 搭建教程
java·spring boot·后端
luom010243 分钟前
springcloud springboot nacos版本对应
spring boot·spring·spring cloud
IT_陈寒1 小时前
Redis性能提升3倍的5个冷门技巧,90%开发者都不知道!
前端·人工智能·后端
LucianaiB1 小时前
OpenClaw 安装后必看!你真的会科学养虾吗?第1天和第47天的Openclaw有什么区别?
后端
代码雕刻家1 小时前
3.6.Maven-依赖管理-依赖范围
java·maven
寻见9032 小时前
智能体开发_07Function Calling道法术器拆解,一文搞懂大模型如何“做事”
人工智能·后端·ai编程
范什么特西2 小时前
狂神报错页面设置
java·tomcat
奋斗小强2 小时前
数据库优化:从慢查询到索引,让系统快 10 倍
后端