Spring线程池学习笔记
- 其他
- 2025-09-13 16:06:01

Spring提供了多种方式来配置和使用线程池,最常见的是通过TaskExecutor和ThreadPoolTaskExecutor。
Spring线程池 TaskExecutor 接口TaskExecutor 是Spring框架中的一个接口,它是对Java的Executor接口的简单封装。它的主要目的是为了提供一个统一的接口来执行任务。
public interface TaskExecutor extends Executor { void execute(Runnable task); } ThreadPoolTaskExecutorThreadPoolTaskExecutor 是Spring提供的一个实现类,它是对Java的ThreadPoolExecutor的封装,提供了更多的配置选项和Spring集成。
配置 ThreadPoolTaskExecutor通过XML配置或Java配置来定义ThreadPoolTaskExecutor。
Java配置
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; @Configuration public class ThreadPoolConfig { @Bean public ThreadPoolTaskExecutor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); // 核心线程数 executor.setMaxPoolSize(10); // 最大线程数 executor.setQueueCapacity(25); // 队列容量 executor.setThreadNamePrefix("MyThread-"); // 线程名前缀 executor.initialize(); return executor; } }XML配置
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="5" /> <property name="maxPoolSize" value="10" /> <property name="queueCapacity" value="25" /> <property name="threadNamePrefix" value="MyThread-" /> </bean> 使用 ThreadPoolTaskExecutor配置好线程池后,通过注入TaskExecutor来使用它。
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; @Service public class MyService { @Autowired private ThreadPoolTaskExecutor taskExecutor; public void executeTask(Runnable task) { taskExecutor.execute(task); } }线程池的参数解释 corePoolSize: 核心线程数,即使线程空闲也不会被回收。maxPoolSize: 最大线程数,当队列满了之后,线程池会创建新的线程,直到达到最大线程数。queueCapacity: 任务队列的容量,当线程数达到核心线程数时,新任务会被放入队列中等待执行。threadNamePrefix: 线程名前缀,方便调试和日志记录。 线程池的工作流程 当有任务提交时,线程池会首先尝试使用核心线程来执行任务。如果核心线程都在忙,任务会被放入队列中等待。如果队列满了,线程池会创建新的线程,直到达到最大线程数。如果线程数达到最大线程数且队列也满了,新的任务会被拒绝(通过设置拒绝策略来处理)。 拒绝策略
当线程池和队列都满了,新的任务会被拒绝。Spring提供了几种拒绝策略:
AbortPolicy: 直接抛出异常(默认策略)。CallerRunsPolicy: 由调用线程来执行任务。DiscardPolicy: 直接丢弃任务。DiscardOldestPolicy: 丢弃队列中最旧的任务,然后尝试重新提交新任务。通过setRejectedExecutionHandler方法来设置拒绝策略。
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); // 满了调用线程执行,认为重要任务 关闭线程池在应用关闭时,确保正确关闭线程池,以释放资源。
taskExecutor.shutdown();异步执行
Spring还提供了@Async注解来支持异步任务执行。 将方法标记为异步,Spring会自动使用配置的线程池来执行这些方法。
import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; @Service public class MyService { @Async public void asyncMethod() { // 异步执行的代码 } } 统一项目管理的线程池封装异常 优雅停机线程池的waitForTasksToCompleteOnShutdown 的 默认参数
private boolean waitForTasksToCompleteOnShutdown = false;Spring 的线程池为什么可以优雅停机,就是继承了DisposableBean的Destroy会被Spring回调
如何捕获线程异常如果不处理的话
线程可以手动设置处理类
自定义未捕获异常时捕获并处理异常信息
@Slf4j public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{ @Override public void uncaughtException(Thread t, Throwable e) { log.error("Exception in thread", e); } }单个线程池测试
Thread thread = new Thread( ()->{ log.error("123"); throw new RuntimeException("异常"); } ); thread.setUncaughtExceptionHandler(new MyUncaughtExceptionHandler()); thread.start(); 项目共用线程池自定义未捕获异常时捕获并处理异常信息
@Slf4j public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{ @Override public void uncaughtException(Thread t, Throwable e) { log.error("Exception in thread", e); } }自定义线程工厂(设计模式——装饰器)
@AllArgsConstructor public class MyThreadFactory implements ThreadFactory { private static final MyUncaughtExceptionHandler UNCAUGHT_EXCEPTION_HANDLER = new MyUncaughtExceptionHandler(); private ThreadFactory originalThreadFactory; /** * @param r a runnable to be executed by new thread instance * @description 额外装饰我们需要的线程 * @return */ @Override public Thread newThread(Runnable r) { Thread thread = originalThreadFactory.newThread(r); thread.setUncaughtExceptionHandler(UNCAUGHT_EXCEPTION_HANDLER); return thread; } }创建ThreadPoolConfig
@Configuration @EnableAsync public class ThreadPoolConfig implements AsyncConfigurer { /** * 项目共用线程池,用于处理核心异步任务。 */ public static final String MYTHREAD_EXECUTOR= "MyThreadExecutor"; /** * 配置项目共用线程池,用于处理核心业务逻辑。 * * 线程池配置: * - 核心线程数:10 * - 最大线程数:10(固定大小线程池) * - 队列容量:200(缓冲待处理任务) * - 线程名称前缀:MyThread-executor- * - 拒绝策略:调用线程执行(保障重要任务不丢失) * * @return 配置完成的线程池实例。 */ @Bean(MYTHREAD_EXECUTOR) @Primary public ThreadPoolTaskExecutor mallchatExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(10); executor.setQueueCapacity(200); executor.setThreadNamePrefix("MyThread-executor-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); executor.setThreadFactory(new MyThreadFactory(executor)); executor.initialize(); return executor; } }测试
@Autowired private ThreadPoolTaskExecutor threadPoolTaskExecutor; @Test public void thread2(){ threadPoolTaskExecutor.execute(()->{ log.error("123"); throw new RuntimeException("异常"); }); } 总结Spring中的线程池配置和使用非常灵活,能够满足大多数并发任务的需求。通过合理配置线程池参数,有效地管理资源,提高应用的并发处理能力。
Spring线程池学习笔记由讯客互联其他栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“Spring线程池学习笔记”
上一篇
Linux注册进程终止处理函数
下一篇
并发编程(线程基础)面试题及原理