Spring boot中的线程池-ThreadPoolTaskExecutor

news/2025/1/11 23:40:45/

一、jdk的阻塞队列:

在这里插入图片描述

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

1、默认注入的ThreadPoolTaskExecutor

视频解说:

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

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

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

@Autowired
ThreadPoolTaskExecutor threadPoolTaskExecutor;

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

@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形式查看:

@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方法就可以了

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类里面有这个方法

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

@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) {@Overridepublic 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<>()

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内使用的线程池本来就是成员变量中的

@Nullable
private ThreadPoolExecutor threadPoolExecutor;

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

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

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

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

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

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

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


http://www.ppmy.cn/news/1028191.html

相关文章

Vue中路由缓存问题及解决方法

一.问题 Vue Router 允许你在你的应用中创建多个视图&#xff0c;并根据路由来动态切换这些视图。默认情况下&#xff0c;当你从一个路由切换到另一个路由时&#xff0c;Vue Router 会销毁前一个路由的组件实例并创建新的组件实例。然而&#xff0c;有时候你可能希望保持一些页…

前端性能优化:懒加载与预加载

在现代网络环境中&#xff0c;网页性能是至关重要的。懒加载和预加载是优化网页加载速度的两种策略&#xff0c;它们可以显著改善用户体验&#xff0c;减少加载时间。本文将为你解释什么是懒加载和预加载&#xff0c;以及它们的应用和好处。 1. 懒加载&#xff08;Lazy Loading…

剑指offer14-I.剪绳子

昨天写的那道题是数组中除了一个元素外其余元素的乘积&#xff0c;这道题自然就想到了把一个数分成两个的和&#xff0c;然后积就是这两个数的积&#xff0c;而这两个数中的每个数又可以分成两个数&#xff0c;所以可以用动态规划的方法&#xff0c;dp[i] dp[j]*dp[i-j]。但是…

02-SSH免密登录(普通用户)

SSH免密登录 说明&#xff1a; ​ 假设我们在 NameNode节点部署在kk01 SecondNameNode节点部署在kk03&#xff0c;ResourceManager 部署在 kk02 ​ kk01上的 NameNode 需要分别到kk01、kk02、kk03上启动DataNode&#xff0c;因此需要配置ssh免密到其他机器 ​ kk02上的 Res…

五、Netty高性能架构设计

目录 5.1 线程模型基本介绍5.2 传统阻塞I/O服务模型5.2.1 工作原理5.2.2 阻塞IO模型特点5.2.3 阻塞IO存在的问题 5.3 Reactor模式5.3.1 针对传统阻塞IO服务模型的2个缺点&#xff0c;解决方案5.3.2 IO复用 线程池&#xff0c;就是Reactor模式设计的基本思想 5.1 线程模型基本介…

Word(1):文章页码设置

1.需求 在文档的封皮页不设置页码&#xff0c;在目录页页码设置为罗马数字&#xff0c;在正文使用阿拉伯数字。 2.解决方法 step1&#xff1a; 在封皮页的最后&#xff0c;点击”插入“-分隔符-分节符&#xff08;下一页&#xff09; step2&#xff1a;在目录页的最后&…

flutter开发实战-WidgetsBinding监听页面前台后台退出状态

flutter开发实战-WidgetsBinding监听页面前台后台退出状态 在开发过程中&#xff0c;经常监听页面前台后台退出状态&#xff0c;这里用到了WidgetsBinding 一、WidgetsBinding是什么&#xff1f; WidgetsBinding是Flutter中最重要的Binding之一&#xff0c;它提供了与Widget…

重复delete 对象指针后的 异常调用栈怪异 解析

Release版VC6 MFC程序 程序正常退出时得到一个如下异常调用栈&#xff1a;​ 0:000> kb# ChildEBP RetAddr Args to Child WARNING: Frame IP not in any known module. Following frames may be wrong. 00 0019eb94 76124f2f 00c3afc8 0019ebdc 001…