1、线程池配置 需要加 @EnableAsync
开启异步线程 或者加载Application.java
上
说明:setWaitForTasksToCompleteOnShutdown(true)
该方法就是这里的关键,用来设置线程池关闭的时候等待所有任务都完成再继续销毁其他的Bean,这样这些异步任务的销毁就会先于Redis线程池的销毁。同时,这里还设置了setAwaitTerminationSeconds(60)
,该方法用来设置线程池中任务的等待时间,如果超过这个时候还没有销毁就强制销毁,以确保应用最后能够被关闭,而不是阻塞住。
可以配置多个 @Bean("asyncTaskExecutor") Bean名称不能一样
@Configuration
@EnableAsync // 开启异步线程
public class AsynConfig {
@Bean
public Executor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数 线程池维护线程的最少数量
executor.setCorePoolSize(10);
// 最大线程数 线程池维护线程的最大数量
executor.setMaxPoolSize(20);
// 缓存队列 队列最大长度 >=mainExecutor.maxSize
executor.setQueueCapacity(200);
// 线程池维护线程所允许的空闲时间
executor.setKeepAliveSeconds(60);
// 线程前缀名称
executor.setThreadNamePrefix("defaultExecutor-");
// 线程池对拒绝任务(无线程可用)的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
return executor;
}
@Bean("asyncTaskExecutor")
public Executor asyncTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 核心线程数 线程池维护线程的最少数量
executor.setCorePoolSize(10);
// 最大线程数 线程池维护线程的最大数量
executor.setMaxPoolSize(20);
// 缓存队列 队列最大长度 >=mainExecutor.maxSize
executor.setQueueCapacity(200);
// 线程池维护线程所允许的空闲时间
executor.setKeepAliveSeconds(60);
// 线程前缀名称
executor.setThreadNamePrefix("asyncTaskExecutor-");
// 线程池对拒绝任务(无线程可用)的处理策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
return executor;
}
}
TestService
import java.util.concurrent.Future;
public interface TestService {
/**
* 异步调用,无返回值
*/
void asyncTask();
/**
* 异步调用,有返回值
*/
Future<String> asyncTask(String s);
}
TestServiceImpl
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import java.util.concurrent.Future;
@Service
public class TestServiceImpl implements TestService {
@Async
@Override
public void asyncTask() {
long startTime = System.currentTimeMillis();
try {
//模拟耗时
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + ":void asyncTask(),耗时:" + (endTime - startTime));
}
@Async("asyncTaskExecutor")
@Override
public Future<String> asyncTask(String s) {
long startTime = System.currentTimeMillis();
try {
//模拟耗时
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
long endTime = System.currentTimeMillis();
System.out.println(Thread.currentThread().getName() + ":Future<String> asyncTask(String s),耗时:" + (endTime - startTime));
return AsyncResult.forValue(s);
}
}