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

          每日一例 | 異步線程優(yōu)化用戶體驗

          共 5480字,需瀏覽 11分鐘

           ·

          2021-05-02 10:22



          背景

          對于后端開發(fā),接口響應時長是一個很關鍵的點,它不僅體現(xiàn)了你寫的接口的性能,同時也代表著用戶體驗,如果你的內(nèi)容響應時間過長,用戶可能早就把網(wǎng)頁關閉了。

          互聯(lián)網(wǎng)行業(yè),有一個用戶體驗原則——2/5/10秒原則。

          就是說,在2秒之內(nèi)給客戶響應被用戶認為是“非常有吸引力”的用戶體驗。

          在5秒之內(nèi)響應客戶被認為“比較不錯”的用戶體驗,在10秒內(nèi)給用戶響應被認為“糟糕”的用戶體驗。

          如果超過10秒還沒有得到響應,那么大多用戶會認為這次請求是失敗的。

          所以很多互聯(lián)網(wǎng)企業(yè),接口發(fā)布上線前,都有一個壓測要求:特定并發(fā)量下,接口的響應時間不能大于200ms。

          在這樣的要求之下,想要提升接口性能,減少用戶等待時間,將部分非實時、不重要、確定無異常等交易(比如訂單處理、辦理完某個業(yè)務給用戶發(fā)消息等),設計成異步處理的方式是一個不錯的選擇,今天我們就來通過一個簡單的示例演示,來了解下異步交易如何實現(xiàn)。

          異步交易演示

          假設,我們有這樣的業(yè)務需求:

          場景一:我們有一個教務管理系統(tǒng),講師導入創(chuàng)建了一門新的課程,并制定了學員,處理課程創(chuàng)建的操作外,我們還需要在課程創(chuàng)建成功后,給學員發(fā)消息。但是發(fā)消息并非是特別重要的操作,這時候我們就可以通過異步交易來發(fā)送消息。

          場景二:我們需要在用戶注冊成功后,給用戶發(fā)送消息(郵件或短信)通知用戶,和場景一類似,發(fā)送消息非必須業(yè)務,為了提升系統(tǒng)響應效率,這時候異步交易是個不錯的選擇。

          場景說完了,下來看我們的簡單應用:

          我們先創(chuàng)建了一個線程池:

          private static ThreadPoolExecutor threadPoolExecutor =
                      new ThreadPoolExecutor(5101,
                              TimeUnit.SECONDS, new LinkedBlockingQueue<>(5));

          然后,我們在核心交易的最后,通過線程池的submit啟動了一個線程:

           threadPoolExecutor.submit(() -> this.sendMessage(messageList));

          通過這個線程去執(zhí)行發(fā)消息的操作,這里我們用到了lamubda表達式,上面的代碼等同于:

          threadPoolExecutor.submit(new Runnable() {
                      @Override
                      public void run() {
                          sendMessage(messageList);
                      }
                  });

          下面是完整代碼:

          /**
           * @author syske
           * @date 2021-05-01 9:34
           */

          public class Example {
              private static ThreadPoolExecutor threadPoolExecutor =
                      new ThreadPoolExecutor(5101,
                              TimeUnit.SECONDS, new LinkedBlockingQueue<>(5));
              /**
               * 發(fā)送消息
               * @param messageList 消息列表
               * @return
               */

              public AtomicInteger sendMessage(List<String> messageList) {
                  AtomicInteger successCount = new AtomicInteger();
                  messageList.forEach(m -> {
                      System.out.println("發(fā)送消息:" + m);
                      successCount.getAndIncrement();
                  });
                  return successCount;
              }

              /**
               * 核心業(yè)務處理
               * @return
               */

              public String deal() {
                  List<String> messageList = new ArrayList<>();
                  // doSomeThing() 其他業(yè)務處理
                  System.out.println("開始組裝消息~Start");
                  for (int i = 0; i < 1000; i++) {
                      int randomInt1 = new Random().nextInt();
                      messageList.add("發(fā)送數(shù)字信息:" + randomInt1);
                  }
                  System.out.println("組裝消息完成~End");
                  System.out.println("開始發(fā)送消息~Start");
                  threadPoolExecutor.submit(() -> this.sendMessage(messageList));
                  System.out.println("發(fā)送消息完成~End");
                  return "業(yè)務處理完成";
              }

              public static void main(String[] args) {
                  Example example = new Example();
                  String result = example.deal();
                  System.out.println(result);
                  threadPoolExecutor.shutdown();
              }
          }

          執(zhí)行上面的方法,你會發(fā)現(xiàn),核心業(yè)務方法在消息沒發(fā)送就已經(jīng)返回了:

          開始組裝消息~Start
          組裝消息完成~End
          開始發(fā)送消息~Start
          發(fā)送消息完成~End
          業(yè)務處理完成
          發(fā)送消息:發(fā)送數(shù)字信息:-123158837
          ……
          ……
          發(fā)送消息:發(fā)送數(shù)字信息:-1354635036

          這樣我們的異步交易就實現(xiàn)了,是不是很簡單呀,如果你的異步業(yè)務是有返回值的,那在啟動線程的時候,你可以通過Callable來實現(xiàn),它和Runnable沒有本質(zhì)區(qū)別,只是它是可以有返回值的。

          總結(jié)

          其實今天的內(nèi)容很簡單,實現(xiàn)過程也很容易,異步交易中真正難的是如何拆分你的業(yè)務,這就需要你自己多思考,多實踐,多總結(jié)了,還是那句話會用這個工具很簡單,但清楚什么時候用這個工具才更重要。好了,各位小伙伴節(jié)日快樂,好好享受假期,但也別忘了學習哦

          項目路徑:

          https://github.com/Syske/example-everyday

          本項目會持續(xù)每日更新,讓我們一起學習,一起進步,遇見更好的自己,加油呀

          - END -


          瀏覽 53
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  欧洲操逼视频 | 欧美亚洲俺也去欧美 | 男人天堂999 | 成人三级小视频 | 人妻精品久久 |