@Async注解的使用

    在实际开发场景中,不需要等待某个方法执行完成而继续往后执行,那么我们可以将这个方法加上@Async注解放入后台线程(或线程池)中异步执行。简单示例代码如下:

先使用@EnableAsync来开启异步的支持,配置一个线程池:

@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)

    @Async("jobExecutor")
    public void asyncUpdateOrders(){
        logger.info(Thread.currentThread().getName()+"异步执行");
    }

程序执行入口主程序:

    @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";
    }

  

执行结果:

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线程执行,结果如下:

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

  

猜你喜欢

转载自www.cnblogs.com/sunshineshen/p/13182324.html