@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异步执行

  

 

posted @   papa虫  阅读(2626)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· 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工具
点击右上角即可分享
微信分享提示