@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異步執行

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM