1、线程池配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
/**
* TODO: 线程池配置,为@Async异步提供支持
* Async注解使用的默认线程池是单例线程池,无法提供足够多的线程执行异步任务
*
* @author WKQ
* @date 2024/3/15
*/
@EnableAsync
@Configuration
public class ExecutorConfig {
@Bean("taskExecutor")
public TaskExecutor defaultThreadPool() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
//核心线程数-计算密集型
threadPoolTaskExecutor.setCorePoolSize(4);
//最大线程数量 io密集型设置为
threadPoolTaskExecutor.setMaxPoolSize(8);
//队列中最大等待任务数
threadPoolTaskExecutor.setQueueCapacity(200);
//线程名前缀
threadPoolTaskExecutor.setThreadNamePrefix("线程池-");
//当达到最大线程数时如何处理新任务-则调用异步方法的线程会自己去执行该任务
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 线程空闲后最大存活时间 30秒
threadPoolTaskExecutor.setKeepAliveSeconds(30);
// 等待所有已提交的任务都执行完毕之后,关闭线程池
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
//初始化线程池
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
2、线程池使用
@Service
public class SomeService {
@Async("taskExecutor")
public void asyncMethod() {
// 这里是异步执行的代码
System.out.println("异步任务正在执行...");
try {
Thread.sleep(2000); // 模拟耗时操作
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException(e);
}
}
}
3、注意事项
- 当使用
@Async
时,注意方法不能在同一个类内自调用并期望异步效果,因为异步任务通过Spring AOP代理当前bean实现,异步任务同通过当前bean的aop代理bean实现异步,如果在当前bean内部自调用,没有通过代理bean调用异步方法 - 确保异步方法是非静态的,一是因为Spring AOP代理通常是基于接口或者类的JDK动态代理实现的