@Async注解的使用
在实际开发场景中,不需要等待某个方法执行完成而继续往后执行,那么我们可以将这个方法加上@Async注解放入后台线程(或线程池)中异步执行。简单示例代码如下:
先使用@EnableAsync来开启异步的支持,配置一个线程池:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | @Configuration @EnableAsync public class ThreadPoolConfig { private static int corePoolSize= 30 ; private static int maxPoolSize= 100 ; private static int queueCapacity= 100 ; private static int keepAliveSeconds= 300 ; @Bean public TaskExecutor jobExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); // 设置核心线程数 executor.setCorePoolSize(corePoolSize); // 设置最大线程数 executor.setMaxPoolSize(maxPoolSize); // 设置队列容量 executor.setQueueCapacity(queueCapacity); // 设置线程活跃时间(秒) executor.setKeepAliveSeconds(keepAliveSeconds); // 设置默认线程名称 executor.setThreadNamePrefix( "async-job-thread-" ); // 设置拒绝策略rejection-policy:当pool已经达到max size的时候,如何处理新任务 CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行 executor.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy()); // 等待所有任务结束后再关闭线程池 executor.setWaitForTasksToCompleteOnShutdown( true ); return executor; } } |
然后在指定需要异步执行方法上加入@Async注解,并自定线程池(当然可以不指定,直接写@Async)
1 2 3 4 | @Async ( "jobExecutor" ) public void asyncUpdateOrders(){ logger.info(Thread.currentThread().getName()+ "异步执行" ); } |
程序执行入口主程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 | @RequestMapping (value = "/asyncUpdateOrders" ) @ResponseBody public String asyncUpdateOrders(HttpServletRequest request) { try { logger.info(Thread.currentThread().getName()+ "主线程请求异步执行asyncUpdateOrders" ); ordersService.asyncUpdateOrders(); logger.info(Thread.currentThread().getName()+ "主线程请求异步执行asyncUpdateOrders结束" ); } catch (Exception e) { logger.error(e.getMessage(), e); return "false" ; } return "true" ; } |
执行结果:
1 2 3 4 | 2020 - 06 - 23 15 : 18 : 59.363 [] [http-nio- 8080 -exec- 1 ] INFO o.s.web.servlet.DispatcherServlet :Completed initialization in 10 ms 2020 - 06 - 23 15 : 18 : 59.396 [] [http-nio- 8080 -exec- 1 ] INFO c.y.p.w.c.OrderProcessController :http-nio- 8080 -exec- 1 主线程请求异步执行asyncUpdateOrders 2020 - 06 - 23 15 : 18 : 59.404 [] [http-nio- 8080 -exec- 1 ] INFO c.y.p.w.c.OrderProcessController :http-nio- 8080 -exec- 1 主线程请求异步执行asyncUpdateOrders结束 2020 - 06 - 23 15 : 18 : 59.404 [] [async-job-thread- 1 ] INFO c.y.p.d.s.impl.OrdersServiceImpl :async-job-thread- 1 异步执行 |
直接写@Async不指定线程池时,如果线程池配置只配了上面jobExecutor一种,则会默认使用该线程池执行,结果和上面一样,如果线程池配置配置了多个线程池,则此时不指定线程池时则会使用系统默认的SimpleAsyncTaskExecutor线程执行,结果如下:
1 2 3 4 | 2020 - 06 - 23 15 : 23 : 38.071 [] [http-nio- 8080 -exec- 1 ] INFO c.y.p.w.c.OrderProcessController :http-nio- 8080 -exec- 1 主线程请求异步执行asyncUpdateOrders 2020 - 06 - 23 15 : 23 : 38.077 [] [http-nio- 8080 -exec- 1 ] INFO o.s.s.a.AnnotationAsyncExecutionInterceptor :More than one TaskExecutor bean found within the context,<br>and none is named 'taskExecutor' . Mark one of them as primary or name it 'taskExecutor' (possibly as an alias) in order to use it for async <br>processing: [jobExecutor, jobBBExecutor] 2020 - 06 - 23 15 : 23 : 38.079 [] [http-nio- 8080 -exec- 1 ] INFO c.y.p.w.c.OrderProcessController :http-nio- 8080 -exec- 1 主线程请求异步执行asyncUpdateOrders结束 2020 - 06 - 23 15 : 23 : 38.079 [] [SimpleAsyncTaskExecutor- 1 ] INFO c.y.p.d.s.impl.OrdersServiceImpl :SimpleAsyncTaskExecutor- 1 异步执行 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具