Spring Boot中@Async的作用


        在Spring中,@Async這個注解用於標記的異步的方法。方法上一旦標記了這個方法,當其它線程調用這個方法時,就會開啟一個新的線程去異步處理業務邏輯。

 此注解的使用說明:

       1、此注解可以用在方法上,也可以用在類上(如果用在類上,這個類中的所有的方法就是異步的)

       2、使用此注解的方法的類對象,需要是spring管理下的bean對象

       3、程序主類或此注解的主類上,需要開啟啟用異步配置,配置上@EnableAsync注解

 

    以Spring boot 為例,啟動類中增加@EnableAsync

@EnableAsync
@SpringBootApplication
public class ManageApplication {

}

異步類:

@Component
public class MyAsyncTask {
@Async
public void asyncCpsItemImportTask(Long platformId, String jsonList){}
}

上面的配置會啟用默認的執行器,異步執行指定的方法。

在業務場景中,有時需要使用自己定義的執行器來跑異步的業務邏輯,那該怎么辦呢?

上面的改造后的代碼如下:

@EnableAsync
@SpringBootApplication
public class ManageApplication {

@Bean("MyExecutor")
public TaskExecutor workExecutor1(){
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setThreadNamePrefix("parseMyTask");
threadPoolTaskExecutor.setCorePoolSize(10);
threadPoolTaskExecutor.setMaxPoolSize(30);
threadPoolTaskExecutor.setQueueCapacity(100);
threadPoolTaskExecutor.afterPropertiesSet();
return threadPoolTaskExecutor;
}

 }

異步類:

@Component
public class MyAsyncTask {
@Async("MyExecutor")
public void asyncCpsItemImportTask(Long platformId, String jsonList){}
}

    注:

         1、 @Async注解由於是異步執行的,在其調用數據庫操作之時,將無法產生事務管理的控制。解決辦法,可以把@Transactional注解放到內部的需要進行事務的方法上

         2、異步的業務邏輯處理場景 有兩種,一個是不需要返回結果,另一種是需要接收返回結果。

              不需要返回結果的比較簡單,就不多說了。

              需要接收返回結果的示例如下:

   @Async("MyExecutor")
    public Future<Map<Long, List>> queryMap(List ids) {
        List<> result = businessService.queryMap(ids);
         ..............
        Map<Long, List> resultMap = Maps.newHashMap();
         ...
        return new AsyncResult<>(resultMap);
    }
調用的方法示例:
    private Map asyncCollectProcessAbilities(List<BindDeviceDO> bindDevices,
                                                            List<BindStaffDO> bindStaffs, String dccId) {
        // 返回值
        Future<Map<Long, List>> asyncResult = MyService.queryMap(ids);
        try {
            finalMap = asyncResult.get();
           
        } catch (InterruptedException | ExecutionException e) {
            ...
        }
        return finalMap;
    }

        3、關於執行器

        Spring用TaskExecutor和TaskScheduler接口提供了異步執行和調度任務的抽象。
        Spring的TaskExecutor和java.util.concurrent.Executor接口時一樣的,這個接口只有一個方法execute(Runnable task)。

        Spring已經內置了許多TaskExecutor的實現,沒有必要自己去實現:
             SimpleAsyncTaskExecutor  這種實現不會重用任何線程,每次調用都會創建一個新的線程。
            SyncTaskExecutor  這種實現不會異步的執行
            ConcurrentTaskExecutor  這種實現是java.util.concurrent.Executor的一個adapter。
             SimpleThreadPoolTaskExecutor  這種實現實際上是Quartz的SimpleThreadPool的一個子類,它監聽Spring的聲明周期回調。
            ThreadPoolTaskExecutor  這是最常用最通用的一種實現。它包含了java.util.concurrent.ThreadPoolExecutor的屬性,並且用TaskExecutor進行包裝。

                默認是用代理去處理@Async的,因此,相同類中的方法調用帶@Async的方法是無法異步的,這種情況仍然是同步。

 


免責聲明!

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



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