在 Spring Boot 2 中,可以使用 @Autowired
注入 线程池 (ThreadPoolTaskExecutor
或 ExecutorService
),从而管理线程的创建和执行。以下是使用 @Autowired
方式注入线程池的完整示例。
1. 通过 @Autowired
注入 ThreadPoolTaskExecutor
步骤 1:配置线程池
创建 ThreadPoolTaskExecutor
的 @Bean
配置:
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
public class ThreadPoolConfig {
@Bean(name = "customTaskExecutor")
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(5); // 核心线程数
executor.setMaxPoolSize(10); // 最大线程数
executor.setQueueCapacity(25); // 任务队列容量
executor.setThreadNamePrefix("Async-Executor-"); // 线程名前缀
executor.initialize();
return executor;
}
}
步骤 2:使用 @Autowired
注入线程池
在 Service 层,通过 @Autowired
注入 ThreadPoolTaskExecutor
并执行任务:
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import java.util.concurrent.Future;
@Service
public class AsyncTaskService {
private static final Logger logger = LoggerFactory.getLogger(AsyncTaskService.class);
@Autowired
@Qualifier("customTaskExecutor") // 通过 @Qualifier 指定 Bean 名称
private ThreadPoolTaskExecutor customTaskExecutor;
// 提交异步任务
public void runAsyncTask() {
customTaskExecutor.execute(() -> {
logger.info("异步任务执行,线程名:{}", Thread.currentThread().getName());
try {
Thread.sleep(2000); // 模拟耗时任务
} catch (InterruptedException e) {
e.printStackTrace();
}
logger.info("异步任务完成,线程名:{}", Thread.currentThread().getName());
});
}
// 提交带返回值的异步任务
public Future<String> runAsyncTaskWithResult() {
return customTaskExecutor.submit(() -> {
logger.info("执行带返回值的异步任务,线程名:{}", Thread.currentThread().getName());
Thread.sleep(2000);
return "任务完成";
});
}
}
步骤 3:在 Controller 中调用
在 Controller 层,通过 @Autowired
调用 AsyncTaskService
:
java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.Future;
@RestController
@RequestMapping("/task")
public class AsyncTaskController {
@Autowired
private AsyncTaskService asyncTaskService;
@GetMapping("/run")
public String runTask() {
asyncTaskService.runAsyncTask();
return "任务已提交";
}
@GetMapping("/runWithResult")
public String runTaskWithResult() throws Exception {
Future<String> result = asyncTaskService.runAsyncTaskWithResult();
return "任务结果:" + result.get();
}
}
2. 通过 @Autowired
注入 ThreadPoolTaskScheduler
(适用于定时任务)
步骤 1:配置 ThreadPoolTaskScheduler
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
@Configuration
public class TaskSchedulerConfig {
@Bean
public ThreadPoolTaskScheduler taskScheduler() {
ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
scheduler.setPoolSize(5); // 线程池大小
scheduler.setThreadNamePrefix("Scheduled-Task-");
scheduler.initialize();
return scheduler;
}
}
步骤 2:在 Service 中使用 @Autowired
注入
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.stereotype.Service;
import java.util.concurrent.ScheduledFuture;
@Service
public class ScheduledTaskService {
private static final Logger logger = LoggerFactory.getLogger(ScheduledTaskService.class);
@Autowired
private ThreadPoolTaskScheduler taskScheduler;
public void scheduleTask() {
ScheduledFuture<?> future = taskScheduler.scheduleAtFixedRate(() -> {
logger.info("执行定时任务,线程名:{}", Thread.currentThread().getName());
}, 5000);
}
}
步骤 3:在 Controller 中调用
java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/schedule")
public class ScheduleTaskController {
@Autowired
private ScheduledTaskService scheduledTaskService;
@GetMapping("/start")
public String startScheduledTask() {
scheduledTaskService.scheduleTask();
return "定时任务已启动";
}
}
3. 通过 @Autowired
注入 ExecutorService
如果你更喜欢 Java 原生的 ExecutorService
,可以使用 @Bean
配置:
步骤 1:定义 ExecutorService
线程池
java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Configuration
public class ExecutorServiceConfig {
@Bean
public ExecutorService fixedThreadPool() {
return Executors.newFixedThreadPool(5);
}
}
步骤 2:在 Service 中注入 ExecutorService
java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.util.concurrent.ExecutorService;
@Service
public class ExecutorServiceTask {
private static final Logger logger = LoggerFactory.getLogger(ExecutorServiceTask.class);
@Autowired
private ExecutorService executorService;
public void executeTask() {
executorService.execute(() -> {
logger.info("执行任务,线程名:{}", Thread.currentThread().getName());
});
}
}
步骤 3:在 Controller 中调用
java
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/executor")
public class ExecutorServiceController {
@Autowired
private ExecutorServiceTask executorServiceTask;
@GetMapping("/run")
public String runTask() {
executorServiceTask.executeTask();
return "任务已提交";
}
}
总结
方式 | 适用场景 | 配置方式 |
---|---|---|
ThreadPoolTaskExecutor |
普通异步任务 (@Async 或 execute ) |
@Autowired private ThreadPoolTaskExecutor |
ThreadPoolTaskScheduler |
定时任务 | @Autowired private ThreadPoolTaskScheduler |
ExecutorService |
原生 Java 线程池 | @Autowired private ExecutorService |
推荐方式
- 使用
ThreadPoolTaskExecutor
结合@Autowired
来管理异步任务(推荐)。 - 使用
ThreadPoolTaskScheduler
进行定时任务调度。 - 避免直接使用
ExecutorService
,因为它不受 Spring 管理,不能动态调整线程池参数。
这样可以 充分利用 Spring Boot 线程池管理,提高系统性能,减少资源消耗,并且代码更易维护! 🚀