Spring 管理线程并实现Runnable接口的任务
1. 定义 Runnable 任务类
将 CheckWorker
声明为 Spring Bean(注意作用域),并实现 Runnable
接口:
@Component
@Scope("prototype") // 原型作用域,避免单例线程安全问题
public class CheckWorker implements Runnable {
private final SomeService someService; // 可注入其他依赖
@Autowired
public CheckWorker(SomeService someService) {
this.someService = someService;
}
@Override
public void run() {
try {
// 执行具体的检查逻辑
someService.performCheck();
} catch (Exception e) {
// 异常处理
Logger.error("CheckWorker执行失败", e);
}
}
}
2. 配置线程池(TaskExecutor)
在 Spring 配置类中定义线程池 Bean,优化资源管理:
@Configuration
@EnableAsync // 启用异步支持(可选,根据需求)
public class ThreadPoolConfig {
@Bean("taskExecutor")
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数(根据机器CPU核心数调整)
executor.setCorePoolSize(4);
// 最大线程数
executor.setMaxPoolSize(8);
// 队列容量(防止内存溢出)
executor.setQueueCapacity(100);
// 线程名前缀
executor.setThreadNamePrefix("CheckWorker-Thread-");
// 拒绝策略(CallerRunsPolicy:由调用线程处理该任务)
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 线程空闲后的存活时间(秒)
executor.setKeepAliveSeconds(60);
// 初始化
executor.initialize();
return executor;
}
}
3. 提交任务到线程池
通过注入 TaskExecutor
提交 CheckWorker
任务:
方式1:手动提交任务
@Service
public class CheckService {
private final TaskExecutor taskExecutor;
private final CheckWorker checkWorker;
@Autowired
public CheckService(
@Qualifier("taskExecutor") TaskExecutor taskExecutor,
CheckWorker checkWorker
) {
this.taskExecutor = taskExecutor;
this.checkWorker = checkWorker;
}
// 触发任务执行
public void startCheck() {
taskExecutor.execute(checkWorker);
// 如果需要多次执行,应使用原型Bean获取新实例
// CheckWorker newWorker = applicationContext.getBean(CheckWorker.class);
// taskExecutor.execute(newWorker);
}
}
方式2:使用 @Async 注解(需配合 @EnableAsync)
修改 CheckWorker
直接使用异步执行:
@Service
public class CheckService {
@Autowired
private CheckWorker checkWorker;
@Async("taskExecutor") // 指定线程池
public void asyncStartCheck() {
checkWorker.run();
}
}
4. 线程池监控与调优
监控指标
-
活跃线程数:
ThreadPoolTaskExecutor.getActiveCount()
-
队列剩余容量:
ThreadPoolTaskExecutor.getThreadPoolExecutor().getQueue().remainingCapacity()
-
已完成任务数:
ThreadPoolTaskExecutor.getThreadPoolExecutor().getCompletedTaskCount()
调优建议
-
核心/最大线程数:根据业务负载和 CPU 核心数动态调整。
-
队列类型:默认使用
LinkedBlockingQueue
,高吞吐场景可换为SynchronousQueue
。 -
拒绝策略:
-
AbortPolicy
(默认):直接抛出异常。 -
DiscardPolicy
:静默丢弃任务。 -
DiscardOldestPolicy
:丢弃队列中最旧的任务。 -
CallerRunsPolicy
:由调用线程执行任务。
-