<strike id="ca4is"><em id="ca4is"></em></strike>
  • <sup id="ca4is"></sup>
    • <s id="ca4is"><em id="ca4is"></em></s>
      <option id="ca4is"><cite id="ca4is"></cite></option>
    • 二維碼
      企資網

      掃一掃關注

      當前位置: 首頁 » 企資快報 » 服務 » 正文

      Mysql進一步優化_性能提升了200_

      放大字體  縮小字體 發布日期:2021-09-20 11:17:53    作者:媒體小英    瀏覽次數:39
      導讀

      前文回顧在《用好組合索引,性能提升10倍不止!》一文中,我們主要使用了CountDownLatch這個類來優化程序的性能,在文末提出了一個思考題:其實,上面的代碼不是允許的,你有更好的優化方法嗎? 很多小伙伴的私信其

      前文回顧

      在《用好組合索引,性能提升10倍不止!》一文中,我們主要使用了CountDownLatch這個類來優化程序的性能,在文末提出了一個思考題:其實,上面的代碼不是允許的,你有更好的優化方法嗎? 很多小伙伴的私信其實或多或少的說出了一些方案,但是沒說到真正的點子上。

      這里,再向小伙伴們提出一個疑問:如果我們不使用CountDownLatch和CompletableFuture,讓你對前文的程序進行優化,你有思路嗎?

      其實思路也很簡單:蕞直接的方式就是創建一個計數器,將計數器的初始值設置為2,當子線程1執行完hasNoOrders = getHasNoOrders(); 這行代碼時,將計數器的值減1,當子線程2執行完 hasNoStock = getHasNoStock(); 這行代碼時,將計數器的值減1。在主線程中,等待計數器的值減為0,然后執行后續的業務操作。

      CountDownLatch類的總體思路也是這樣,小伙伴們可以根據這個思路自行實現程序性能的優化,我就不再這里絮叨啦。

      能否進一步優化?

      我們先來看看之前程序的優化效果圖。

      通過仔細的分析,我們就會發現:雖然getHasNoOrders()getHasNoStock()這兩個方法實現了并行操作,但是getHasNoOrders()方法和getHasNoStock()方法和checkData()方法與saveCheckResult()方法之間還是串行的,如果能夠讓他們之間的操作并行化,那么系統的性能就可以得到進一步提升了。如下圖所示。

      如何實現上圖所示的優化呢?接下來,我們先說說進一步優化的總體思路。

      進一步優化思路

      查詢未校對的訂單方法getHasNoOrders()和查詢未校對的庫存方法getHasNoStock()能夠并行執行,校對數據的方法 checkData()還要依賴getHasNoOrders()方法和getHasNoStock()方法的結果,很明顯可以使用CompletableFuture來優化,那除了CompletableFuture還有其他的方式嗎?今天,我們先不講CompletableFuture,先來看看其他的優化方式。

      大家認真思考下,上述的場景中,一個方法的執行需要等待另外兩個方法的執行結果,是不是有點生產者-消費者的意思呢?

      有些小伙伴可能會說:這哪是生產者和消費者模型啊?我們仔細想一下:兩次查詢未校對的數據就是生產者,校對數據的操作是消費者。

      我們可以使用隊列來保存生產者生產的數據,而消費者就從這個隊列中消費數據。

      由于查詢未校對的訂單方法getHasNoOrders()和查詢未校對的庫存方法getHasNoStock()是在兩個不同的線程中執行的,這里,在具體實現時,我們可以使用兩個隊列分別保存未校對的訂單數據和未校對的庫存數據,校對數據的操作每次從隊列1中取出未校對的訂單數據,從隊列2中取出未校對的庫存數據,然后再執行數據的校對操作。

      接下來,我們再思考一個問題:就是如何使用兩個隊列實現完全的并行化。

      一個簡單的方案就是在線程1中執行查詢未校對訂單的數據,在線程2中執行查詢未校對庫存的數據,當線程1和線程2分別生產完一條數據時,通知線程3執行數據的校對操作。這里,有個關鍵的點就是線程1和線程2的執行步調要一致,不能一個線程執行的太快,一個線程執行的太慢。

      很顯然,線程1和線程2之間會存在相互等待的現象,說到這里,小伙伴們是不是就有解決方案啦?

      我們先來說說優化的總體思路吧: 首先,進一步優化存在兩個難點:一個是線程1和線程2執行的步調要一致,另外就是線程1和線程2中每次方法執行完畢后,要通知線程3執行數據校對操作。

      我們也可以使用計數器的方式實現,計數器的初始值為2,線程1執行完getHasNoOrders()方法時,對計數器減1,線程2執行完getHasNoStock()方法時,對計數器減1。如果計數器的值大于0時,則線程1等待或者線程2等待。如果計數器的值等于0,則通知線程3執行數據校對操作,并重新喚醒等待中的線程1或者線程2。同時,需要我們將計數器的值重新設置為2,以此往復實現程序的優化效果。

      有小伙伴可能會說:這也太麻煩了吧!哈哈,自己實現確實挺麻煩的,不過Java并發類庫中為我們準備好了一個實現上述場景的類——沒錯,可以使用Java并發類庫中的 CyclicBarrier 類實現。

      使用CyclicBarrier進一步優化

      使用CyclicBarrier進一步優化的具體方案就是:首先創建一個計數器初始值為2的CyclicBarrier對象,在構造方法中傳入一個回調函數,在回調函數中執行數據的校對操作,當計數器的值減為0時,就會執行這個回調函數。

      在線程1中執行完getHasNoOrders()方法并將結果放入隊列1后,執行barrier.await()將計數器減1,同時等待計數器的值減為0。在線程2中執行完getHasNoStock()方法并將結果放入隊列2后,執行barrier.await()將計數器減1,同時等待計數器的值減為0。

      當計數器的值減為0時,線程1和線程2繼續向下執行,同時會調用回調函數來執行數據的校對操作。

      不僅如此,CyclicBarrier類還能夠自動重置計數器的值,當計數器的值減為0時,它又會被自動重置為初始值,這個功能使用起來也很方便。

      接下來,我們看一下使用CyclicBarrier類優化后的核心偽代碼,如下所示。

      `// 訂單隊列
      Vector<Order> orderQueue;
      // 庫存隊列
      Vector<Stock> stockQueue;
      //創建查詢未校對訂單和未校對庫存的線程池
      Executor executor = Executors.newFixedThreadPool(2);
      //執行數據校對的線程池
      Executor checkExecutor = Executors.newFixedThreadPool(1);

      final CyclicBarrier barrier =
      new CyclicBarrier(2, ()->{
      executor.execute(() -> checkDataAndSaveResult());
      });

      void checkDataAndSaveResult(){
      Order o = orderQueue.remove(0);
      Stock s = stockQueue.remove(0);
      //校對數據并返回結果
      checkResult = checkData(o, a);
      //將結果信息保存到數據校對信息表中
      saveCheckResult(checkResult);
      }

      void checkAllOrdersAndStock(){
      //檢測是否存在未對賬訂單
      checkOrders = checkOrders();
      while(checkOrders != null){
      executor.execute(()->{
      //查詢未校對的訂單信息
      hasNoOrders = getHasNoOrders();
      orderQueue.add(hasNoOrders);
      barrier.await();
      });
      executor.execute(()->{
      //查詢未校對的庫存記錄
      hasNoStock = getHasNoStock();
      stockQueue.add(hasNoStock);
      barrier.await();
      });
      }
      }
      `

      至此,整個程序的優化操作就完成了。

      總結

      在整個程序的優化過程中,我們開始使用了CountDownLatch優化程序,后面又使用了CyclicBarrier優化程序。它兩個的區別就是:

    • CountDownLatch主要的使用場景就是一個線程等待多個線程執行完畢后再執行;而CyclicBarrier主要的使用場景為多個線程相互等待。
    • CountDownLatch的計數器減為0時,無法進行重置,不可復用;而CyclicBarrier的計數器減為0時,可以自動將計數器的值重置為初始值,可以復用。
    • CountDownLatch無法設置回調函數;而CyclicBarrier可以設置回調函數,當計數器的值減為0時,可以自動執行回調函數的邏輯。

      好了,今天就到這兒吧,我們下期見~~

    •  
      (文/媒體小英)
      免責聲明
      本文僅代表作發布者:媒體小英個人觀點,本站未對其內容進行核實,請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內容,一經發現,立即刪除,需自行承擔相應責任。涉及到版權或其他問題,請及時聯系我們刪除處理郵件:weilaitui@qq.com。
       

      Copyright ? 2016 - 2025 - 企資網 48903.COM All Rights Reserved 粵公網安備 44030702000589號

      粵ICP備16078936號

      微信

      關注
      微信

      微信二維碼

      WAP二維碼

      客服

      聯系
      客服

      聯系客服:

      在線QQ: 303377504

      客服電話: 020-82301567

      E_mail郵箱: weilaitui@qq.com

      微信公眾號: weishitui

      客服001 客服002 客服003

      工作時間:

      周一至周五: 09:00 - 18:00

      反饋

      用戶
      反饋

      午夜久久久久久网站,99久久www免费,欧美日本日韩aⅴ在线视频,东京干手机福利视频
        <strike id="ca4is"><em id="ca4is"></em></strike>
      • <sup id="ca4is"></sup>
        • <s id="ca4is"><em id="ca4is"></em></s>
          <option id="ca4is"><cite id="ca4is"></cite></option>
        • 主站蜘蛛池模板: **俄罗斯毛片免费| 久久精品视频99精品视频150| av在线手机播放| 男人边吃奶边爱边做视频刺激| 成人精品视频一区二区三区尤物 | 一级黄色在线视频| 羞羞社区在线观看视频| 成人欧美一区二区三区的电影 | 亚洲精品视频在线播放| AAAAA级少妇高潮大片免费看| 猫咪免费观看人成网站在线| 天天操视频夜夜| 国产精品自产拍在线网站| 亚洲毛片免费观看| 18观看免费永久视频| 欧美三级中文字幕在线观看| 国产特级毛片AAAAAA视频| 亚洲av无码专区在线观看下载| 日本三级韩国三级美三级91| 日韩激情视频在线| 国产乱人激情H在线观看| 中文在线免费不卡视频| 粉嫩小仙女脱内衣喷水自慰| 日本动态120秒免费| 四虎成人精品国产永久免费无码 | 人人干人人干人人干| 91精品视频在线| 桃花直播下载免费观看| 国内自产少妇自拍区免费| 亚洲国产精品综合久久网各| 日本xxxⅹ色视频在线观看网站| 日韩欧国产精品一区综合无码| 国产一区在线看| lisaannxxxxx| 欧美无人区码卡二三卡四卡| 国产成人精品免费午夜app| 中文综合在线观| 男人桶女人j的视频在线观看| 国产精品酒店视频| 久久影院最新消息| 精品国产青草久久久久福利|