第一步:在Application启动类上面加上@EnableAsync注解
@SpringBootApplication
@EnableAsync
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
第二步:定义[线程池]
@Configuration
@EnableAsync
@Component
public class AsyncConfig {
@Bean("asyncTaskExecutor")
public TaskExecutor asyncTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
// 设置核心线程数
executor.setCorePoolSize(20);
// 设置最大线程数
executor.setMaxPoolSize(100);
// 设置队列容量
executor.setQueueCapacity(1000);
// 设置线程活跃时间(秒)
executor.setKeepAliveSeconds(300);
// 设置默认线程名称
executor.setThreadNamePrefix("async-thread-pool-");
// 设置拒绝策略
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
// 等待所有任务结束后再关闭线程池
executor.setWaitForTasksToCompleteOnShutdown(true);
return executor;
}
}
第三步:在异步方法上添加@Async
@Slf4j
@Service
@Component
public class AsyncServiceImpl implements AsyncService {
@Async("asyncTaskExecutor")
@Override
public void testA() {
try {
System.out.println("开始testA");
Thread.sleep(3000);
System.out.println("完成testA");
Thread currentThread = Thread.currentThread();
System.out.println("任务testA,当前线程:" + currentThread.getName());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
@Override
public void testB() {
try {
System.out.println("开始testB");
Thread.sleep(3000);
System.out.println("完成testB");
Thread currentThread = Thread.currentThread();
System.out.println("任务testB,当前线程:" + currentThread.getName());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
第四步:测试
public class Test {
@Autowired
private AsyncService asyncService;
@Test
public void testSyncTasks() throws Exception {
long start = currentTimeMillis();
asyncService.testA();
long end = currentTimeMillis();
System.out.println("时间testA:" + (end - start));
long start1 = currentTimeMillis();
asyncService.testB();
long end1 = currentTimeMillis();
System.out.println("时间testB:" + (end1 - start1));
}
}
输出结果:
时间testA:2
开始testB
开始testA
完成testA
完成testB
任务testA,当前线程:async-thread-pool-1
时间testB:3002
异步方法@Async注解失效情况:
(1)在@SpringBootApplication启动类没有添加注解@EnableAsync
(2)调用方法和异步方法写在同一个类,需要在不同的类才能有效。
(2)调用的是静态(static )方法
(3)调用(private)私有化方法
个别失效报错情况:
报错一:提示需要在@EnableAsync上设置proxyTargetClass=true来强制使用基于cglib的代理。注解上加上即可。
@EnableAsync(proxyTargetClass = true)
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching
————————————————
网友评论