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

相关推荐
cipher19 分钟前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
毅航1 小时前
自然语言处理发展史:从规则、统计到深度学习
人工智能·后端
JxWang051 小时前
Task04:字符串
后端
树獭叔叔2 小时前
10-让模型更小更聪明,学而不忘:知识蒸馏与持续学习
后端·aigc·openai
JxWang052 小时前
Task02:链表
后端
只会cv的前端攻城狮3 小时前
Elpis-Core — 融合 Koa 洋葱圈模型实现服务端引擎
前端·后端
codetown3 小时前
2026年Zig编程语言权威指南:从系统级底层架构到现代软件工程实践
后端·程序员
cg334 小时前
cc-connect,十分钟帮你把 claude code 连接到微信,飞书,钉钉等等平台
后端·openai
用户1427868669324 小时前
Java多态的底层真相:JVM到底怎么知道该调哪个方法?(面试高频)
后端