<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          面試問,@EnableAsync 和 @Async

          共 3839字,需瀏覽 8分鐘

           ·

          2022-06-01 16:17

          在我們的日常開發(fā)中,我們偶爾會遇到在業(yè)務層中我們需要同時修改多張表的數(shù)據(jù)并且需要有序的執(zhí)行,如果我們用往常的同步的方式,也就是單線程的方式來執(zhí)行的話,可能會出現(xiàn)執(zhí)行超時等異常造成請求結(jié)果失敗,及時成功,前端也需要等待較長時間來獲取響應結(jié)果,這樣不但造成了用戶體驗差,而且會經(jīng)常出現(xiàn)請求執(zhí)行失敗的問題,在這里我們一般會采用3種方式來處理,如下所示:

          在采用三種方式之前,我們所有來觀察一下使用同步的方式實現(xiàn)的結(jié)果:

          1.我們定義一個TestController,如下所示:

          @RestController
          public?class?TestController?{
          ?
          ????@Autowired
          ????private?TestService?service;

          ????/**
          ?????*?使用傳統(tǒng)方式測試
          ?????*/

          ????@GetMapping("/test")
          ????public?void?test()?{
          ????????System.out.println("獲取主線程名稱:"?+?Thread.currentThread().getName());
          ????????service.serviceTest();
          ????????System.out.println("執(zhí)行成功,返回結(jié)果");
          ????}
          }

          2. 我們定義TestService,如下所示:

          @Service
          public?class?TestAsyncService?{
          ?
          ????public?void?serviceTest()?{
          ????????????//?這里執(zhí)行實際的業(yè)務邏輯,在這里我們就是用一個簡單的遍歷來模擬
          ????????????Arrays.stream(new?int[]{1,2,3,4,5,6,7,8,9,10}).forEach(?t?->?{
          ????????????????try?{
          ????????????????????Thread.sleep(100);
          ????????????????}?catch?(InterruptedException?e)?{
          ????????????????????e.printStackTrace();
          ????????????????}
          ????????????????System.out.println("獲取number為:"?+?t)?;
          ????????????});
          ????}
          }

          我們執(zhí)行請求http://localhost:8888/test,結(jié)果顯示如下:

          接下來我們采用我們所說的3種方式來實現(xiàn):

          1.使用線程池的方式來實現(xiàn)

          1)定義TestAsyncController中的test()方法,如下所示:

          @RestController
          public?class?TestAsyncController?{
          ?
          ????@Autowired
          ????private?TestAsyncService?asyncService;
          ????
          ????/**
          ?????*?使用傳統(tǒng)方式測試
          ?????*/

          ????@GetMapping("/test")
          ????public?void?test()?{
          ????????System.out.println("獲取主線程名稱:"?+?Thread.currentThread().getName());
          ????????/**
          ?????????*??這里也可以采用以下方式使用,但是使用線程池的方式可以很便捷的對線程管理(提高程序的整體性能),
          ?????????*??也可以減少每次執(zhí)行該請求時都需要創(chuàng)建一個線程造成的性能消耗
          ?????????*??new?Thread(()?->{
          ?????????*??run方法中的業(yè)務邏輯
          ?????????*??})
          ?????????*/

          ?
          ????????/**
          ?????????*?定義一個線程池
          ?????????*?核心線程數(shù)(corePoolSize):1
          ?????????*?最大線程數(shù)(maximumPoolSize):?1
          ?????????*?保持連接時間(keepAliveTime):50000
          ?????????*?時間單位?(TimeUnit):TimeUnit.MILLISECONDS(毫秒)
          ?????????*?阻塞隊列?new?LinkedBlockingQueue()
          ?????????*/

          ????????ThreadPoolExecutor?executor?=?new?ThreadPoolExecutor(1,5,50000,?TimeUnit.MILLISECONDS,?new?LinkedBlockingQueue());
          ????????//?執(zhí)行業(yè)務邏輯方法serviceTest()
          ????????executor.execute(new?Runnable()?{
          ????????????@Override
          ????????????public?void?run()?{
          ????????????????asyncService.serviceTest();
          ????????????}
          ????????});
          ????????System.out.println("執(zhí)行完成,向用戶響應成功信息");
          ????}
          }

          2)定義TestAsyncServiceTestService中的test()相同,在這就不顯示了;

          3)查看運行結(jié)果:

          我們發(fā)現(xiàn)在主線程中使用線程池中的線程來實現(xiàn),程序的執(zhí)行結(jié)果表明,主線程直接將結(jié)果進行了返回,然后才是線程池在執(zhí)行業(yè)務邏輯,減少了請求響應時長。

          2. 使用注解@EnableAsync和@Async來實現(xiàn)

          (1)雖然這樣實現(xiàn)了我們想要的結(jié)果,但是,但是我們發(fā)現(xiàn)如果我們在多個請求中都需要這種異步請求,每次都寫這么冗余的線程池配置會不會,這種問題當然會被我們強大的spring所觀察到,所以spring為了提升開發(fā)人員的開發(fā)效率,使用@EnableAsync來開啟異步的支持,使用@Async來對某個方法進行異步執(zhí)行。

          TestAsyncController如下所示:

          @RestController
          public?class?TestAsyncController?{
          ?
          ????@Autowired
          ????private?TestAsyncService?asyncService;
          ?
          ????/**
          ?????*?使用@Async來實現(xiàn)
          ?????*/

          ????@GetMapping("/test")
          ????public?void?test()?{
          ????????System.out.println("獲取主線程名稱:"?+?Thread.currentThread().getName());
          ????????//?異步調(diào)用
          ????????asyncService.serviceTest();
          ????????System.out.println("執(zhí)行完成,向用戶響應成功信息");
          ????}

          (2)TestAsyncService如下所示:

          @Service
          @EnableAsync
          public?class?TestAsyncService?{
          ?
          ?
          ????/**
          ?????*?采用異步執(zhí)行
          ?????*/

          ????@Async
          ????public?void?serviceTest()?{
          ????????????//?這里執(zhí)行實際的業(yè)務邏輯,在這里我們就是用一個簡單的遍歷來模擬
          ????????????Arrays.stream(new?int[]{1,2,3,4,5,6,7,8,9,10}).forEach(?t?->?{
          ????????????????try?{
          ????????????????????Thread.sleep(100);
          ????????????????}?catch?(InterruptedException?e)?{
          ????????????????????e.printStackTrace();
          ????????????????}
          ????????????????System.out.println("獲取number為:"?+?t)?;
          ????????????});
          ????}

          (3)執(zhí)行結(jié)果如下:

          結(jié)果與使用線程池的結(jié)果一致,但是簡化了我們編寫代碼的邏輯,@Async注解幫我們實現(xiàn)了創(chuàng)建線程池的繁瑣,提高了我們的開發(fā)效率。

          3. 使用消息隊列(mq)來實現(xiàn)

          當我們涉及的請求在業(yè)務邏輯中一次性操作很多很多的數(shù)據(jù),例如:一個請求執(zhí)行相關業(yè)務操作后,將操作日志插入到數(shù)據(jù)庫中,我們可以使用@Async來實現(xiàn),但是這樣增加了業(yè)務和非業(yè)務關系的冗余性(同時如何并發(fā)量很大,我們使用@Async處理,無法提升我們系統(tǒng)的整體系統(tǒng),這樣很容易造成服務器宕機),所以我們對于這種情況,我們會采用mq來實現(xiàn),將業(yè)務邏輯和非業(yè)務邏輯進行隔離執(zhí)行,互不影響,非業(yè)務邏輯不會影響到執(zhí)行業(yè)務邏輯的結(jié)果和主機性能,對于mq的處理,我會在后續(xù)添加。

          來源:blog.csdn.net/qq_38796327/article/details/90599867

          ——————END——————

          歡迎關注“Java引導者”,我們分享最有價值的Java的干貨文章,助力您成為有思想的Java開發(fā)工程師!

          瀏覽 33
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色综合久久天天综合网 | 热的无码 | 99热都是精品 | 人人操人人看人人干 | 在线国内自拍 |