Spring创建异步线程池方式
在Java 11中,可以通过多种方式创建异步线程池,包括使用原生的ExecutorService
和Spring的异步支持(如@Async
注解结合线程池)。以下是具体实现方式。
方式 1:使用原生ExecutorService
Java 11 的ExecutorService
提供灵活的线程池管理,可以使用Executors
或直接创建ThreadPoolExecutor
。
示例代码:
import java.util.concurrent.*;
public class AsyncThreadPoolExample {
public static void main(String[] args) {
// 创建线程池
ExecutorService executorService = new ThreadPoolExecutor(
4, // 核心线程数
8, // 最大线程数
60L, // 空闲线程存活时间
TimeUnit.SECONDS, // 时间单位
new LinkedBlockingQueue<>(100), // 队列容量
Executors.defaultThreadFactory(), // 线程工厂
new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);
// 提交任务
for (int i = 0; i < 10; i++) {
int taskNumber = i;
executorService.submit(() -> {
System.out.println("Executing task " + taskNumber + " by " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// 关闭线程池
executorService.shutdown();
}
}
自定义参数:
- 核心线程数:线程池保留的线程数量,用于处理任务。
- 最大线程数:线程池的最大线程数量。
- 队列:任务等待队列,处理线程不足时任务会被加入队列。
- 拒绝策略:任务无法执行时的处理方式,如抛出异常、丢弃任务等。
方式 2:使用 Spring 的异步线程池
Spring 提供了对异步任务的内置支持,可以结合@Async
注解和自定义线程池使用。
步骤 1:配置线程池
创建一个Spring配置类:
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 AsyncConfig {
@Bean(name = "asyncExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(4); // 核心线程数
executor.setMaxPoolSize(8); // 最大线程数
executor.setQueueCapacity(50); // 队列容量
executor.setThreadNamePrefix("AsyncExecutor-"); // 线程名前缀
executor.initialize();
return executor;
}
}
步骤 2:启用异步支持
在Spring的主类或配置类中启用异步功能:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class AsyncApplication {
public static void main(String[] args) {
SpringApplication.run(AsyncApplication.class, args);
}
}
步骤 3:创建异步任务
在需要异步执行的方法上添加@Async
注解,并指定线程池:
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncService {
@Async("asyncExecutor")
public void performTask(int taskId) {
System.out.println("Executing task " + taskId + " by " + Thread.currentThread().getName());
try {
Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
步骤 4:调用异步方法
注入服务并调用异步方法:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class AsyncController {
@Autowired
private AsyncService asyncService;
@GetMapping("/async")
public String executeAsyncTasks() {
for (int i = 0; i < 5; i++) {
asyncService.performTask(i);
}
return "Tasks submitted!";
}
}
总结
- 方式 1:原生线程池更灵活,适合于需要完全控制线程池行为的场景。
- 方式 2:Spring异步线程池结合
@Async
注解,简化了异步任务的开发,是Spring项目的推荐方式。
选择方式取决于项目需求和技术栈。如果在Spring项目中,优先使用方式 2。