前提:
在不考虑公司自己的异步任务工具类,自定义异步注解这些,只考虑通用的实现方式,包括一些开源的第三方jar包实现
以下都是一些自己常用的实现方式
不需要异步任务结果的情况下:
1.如果实现场景简单,并发不高,可以考虑使用juc包下的Executors
- Executors.newSingleThreadExecutor() 创建只有一个线程的线程池
- Executors.newFixedThreadPool(int nThreads) 创建具有指定数量线程数的线程池
- Executors.newCachedThreadPool() 创建一个线程池,线程池中的线程空闲时间超过60秒就销毁线程
- Executors.newScheduledThreadPool(2) 创建有定时功能的线程池
举一个简单使用例子
public static void main(String[] args) throws Exception{
// 创建线程池
ExecutorService es = Executors.newFixedThreadPool(2);
for (int i = 0; i < 5; i++) {
es.execute(() -> {
//此处实现异步逻辑
System.out.println(Thread.currentThread().getName()+" 线程运行");
});
}
// 关闭线程池
es.shutdown();
2.如果考虑对线程池有要求,并且有一定的复用性,可以考虑使用spring下的Async注解+ThreadPoolTaskExecutor类去使用
Async注解可以使被修饰的方法成为异步方法,并且可以配置自定义的线程池使用,如果不配置默认使用的spring的无边界线程池,当执行被Async修饰的方法时,会调用配置的线程池异步执行。而ThreadPoolTaskExecutor是spring自带的线程池,可以理解为是对ThreadPoolExecutor的再封装。
举一个简单使用例子
TheadPoolTaskExecutor配置类
@Configuration
@Slf4j
public class ExecutorConfig {
@Value("${async.executor.thread.core_pool_size}")
private int corePoolSize;
@Value("${async.executor.thread.max_pool_size}")
private int maxPoolSize;
@Value("${async.executor.thread.queue_capacity}")
private int queueCapacity;
@Value("${async.executor.thread.name.prefix}")
private String namePrefix;
@Value("${async.executor.thread.keep_alive_seconds}")
private int keepAliveSeconds;
@Bean(name = "asyncTaskExecutor")
public ThreadPoolTaskExecutor taskExecutor() {
log.info("启动");
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数
executor.setCorePoolSize(corePoolSize);
// 最大线程数
executor.setMaxPoolSize(maxPoolSize);
// 任务队列大小
executor.setQueueCapacity(queueCapacity);
// 线程前缀名
executor.setThreadNamePrefix(namePrefix);
// 线程的空闲时间
executor.setKeepAliveSeconds(keepAliveSeconds);
// 拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// 线程初始化
executor.initialize();
return executor;
}
}
异步场景实现类
@Component
@Slf4j
public class ThreadTest {
@Async("asyncTaskExecutor")
public void ceshi() {
//此处实现异步逻辑
System.out.println(Thread.currentThread().getName()+" 线程运行");
}
测试类
// 在启动类上添加 @EnableScheduling 注解
@SpringBootApplication
@EnableScheduling
public class SpringBootStudyApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootStudyApplication.class, args);
}
}
@Component
public class listennerTest3 {
@Autowired
private ThreadTest t;
public void run() {
t.ceshi();
}
}
需要异步任务结果的情况下:
可以使用CompletableFuture,注意获取结果的同时是同步阻塞的
具体使用参考:blog.csdn.net/zsx_xiaoxin…