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的方法是無法異步的,這種情況仍然是同步。

發佈了15 篇原創文章 · 獲贊 3 · 訪問量 1214
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章