在 Spring Boot 2 中,可以使用 @Autowired
注入 線程池(ThreadPoolTaskExecutor
或 ExecutorService
),從而管理線程的創建和執行。以下是使用 @Autowired
方式注入線程池的完整示例。
1. 通過 @Autowired
注入 ThreadPoolTaskExecutor
步驟 1:配置線程池
創建 ThreadPoolTaskExecutor
的 @Bean
配置:
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
并執行任務:
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
:
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 {@Autowiredprivate 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
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;@Configuration
public class TaskSchedulerConfig {@Beanpublic ThreadPoolTaskScheduler taskScheduler() {ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();scheduler.setPoolSize(5); // 線程池大小scheduler.setThreadNamePrefix("Scheduled-Task-");scheduler.initialize();return scheduler;}
}
步驟 2:在 Service 中使用 @Autowired
注入
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);@Autowiredprivate ThreadPoolTaskScheduler taskScheduler;public void scheduleTask() {ScheduledFuture<?> future = taskScheduler.scheduleAtFixedRate(() -> {logger.info("執行定時任務,線程名:{}", Thread.currentThread().getName());}, 5000);}
}
步驟 3:在 Controller 中調用
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 {@Autowiredprivate ScheduledTaskService scheduledTaskService;@GetMapping("/start")public String startScheduledTask() {scheduledTaskService.scheduleTask();return "定時任務已啟動";}
}
3. 通過 @Autowired
注入 ExecutorService
如果你更喜歡 Java 原生的 ExecutorService
,可以使用 @Bean
配置:
步驟 1:定義 ExecutorService
線程池
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 {@Beanpublic ExecutorService fixedThreadPool() {return Executors.newFixedThreadPool(5);}
}
步驟 2:在 Service 中注入 ExecutorService
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);@Autowiredprivate ExecutorService executorService;public void executeTask() {executorService.execute(() -> {logger.info("執行任務,線程名:{}", Thread.currentThread().getName());});}
}
步驟 3:在 Controller 中調用
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 {@Autowiredprivate 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 線程池管理,提高系統性能,減少資源消耗,并且代碼更易維護! 🚀