广东深圳网站,亦庄附近的网站建设公司,攀枝花seo,营销网站建设费用Spring提供了多种方式来配置和使用线程池#xff0c;最常见的是通过TaskExecutor和ThreadPoolTaskExecutor。 Spring线程池
TaskExecutor 接口
TaskExecutor 是Spring框架中的一个接口#xff0c;它是对Java的Executor接口的简单封装。它的主要目的是为了提供一个统一的接口… Spring提供了多种方式来配置和使用线程池最常见的是通过TaskExecutor和ThreadPoolTaskExecutor。 Spring线程池
TaskExecutor 接口
TaskExecutor 是Spring框架中的一个接口它是对Java的Executor接口的简单封装。它的主要目的是为了提供一个统一的接口来执行任务。
public interface TaskExecutor extends Executor {void execute(Runnable task);
}ThreadPoolTaskExecutor
ThreadPoolTaskExecutor 是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 {Beanpublic ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor new ThreadPoolTaskExecutor();executor.setCorePoolSize(5); // 核心线程数executor.setMaxPoolSize(10); // 最大线程数executor.setQueueCapacity(25); // 队列容量executor.setThreadNamePrefix(MyThread-); // 线程名前缀executor.initialize();return executor;}
}XML配置
bean idtaskExecutor classorg.springframework.scheduling.concurrent.ThreadPoolTaskExecutorproperty namecorePoolSize value5 /property namemaxPoolSize value10 /property namequeueCapacity value25 /property namethreadNamePrefix valueMyThread- /
/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 {Autowiredprivate 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 {Asyncpublic void asyncMethod() {// 异步执行的代码}
}统一项目管理的线程池封装异常
优雅停机 线程池的waitForTasksToCompleteOnShutdown 的 默认参数 private boolean waitForTasksToCompleteOnShutdown false;Spring 的线程池为什么可以优雅停机就是继承了DisposableBean的Destroy会被Spring回调 如何捕获线程异常 如果不处理的话 线程可以手动设置处理类 自定义未捕获异常时捕获并处理异常信息 Slf4j
public class MyUncaughtExceptionHandler implements Thread.UncaughtExceptionHandler{Overridepublic 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{Overridepublic 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*/Overridepublic 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)Primarypublic 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;}
}测试 Autowiredprivate ThreadPoolTaskExecutor threadPoolTaskExecutor;
Testpublic void thread2(){threadPoolTaskExecutor.execute(()-{log.error(123);throw new RuntimeException(异常);});}总结
Spring中的线程池配置和使用非常灵活能够满足大多数并发任务的需求。通过合理配置线程池参数有效地管理资源提高应用的并发处理能力。