<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Loading

      【線程池】如何正確的配置一個線程池

      我們在創建自己的線程池時,會時常因為不知道給核心線程數或者最大線程數設置多少為好,其實這個時需要看你的線程池的使用場景和服務器CUP的配置,根據這些前置條件,我們再去判斷如何去設置合適的線程數,并不是我們想設置多少線程數大小就可以設置多少,這樣可能會導致線程發揮不到最大的性能,甚至還有可能會導致服務OOM堆棧溢出的風險。

      使用場景

      CPU密集型任務

      當我們遇到那種需要大量使用CUP的任務時,比如加密、解密、壓縮、計算等一系列操作,這種情況理想的線程核心數是CPU核心數的1~2倍,不宜設置的太多。如果設置太多的線程數,當線程任務越來越多的時候,導致CUP的線程的壓力會越來越大并且線程的數量也會越來越多,導致CPU去切換線程上下文的時間成本會越來越多,這樣不僅不會提升線程的性能,可能還會導致線程的的性能越來越低。

      耗時IO型任務

      耗時IO其實就是不太耗CUP的資源,只是會在執行上會有一定的等待時間,比如操作數據庫,讀取大文件,或者請求接口等。當我們從數據庫查詢一個很大的數據時,需要等待很久的時間,其實這個等待的時間他并不消耗CPU的資源。所以在這種場景上,我們設置的最大線程數其實可以大于核心線程數很多倍。因為他大部分線程都不怎么消耗線程資源。

      計算公式

      那么場景有了,我該如何去獲取我們可以設置的核心線程數的值呢?
      可以看到下面這個公式

      《Java并發編程實戰》的作者 Brain Goetz 推薦的計算方法:

      線程數 = CPU 核心數 *(1+平均等待時間/平均工作時間)
      

      可以看到

      • 平均等待時間越長,就代表是耗時IO型任務,這時線程數就會越大。
      • 平均工作時間越長,就代表是CPU密集型任務,這時線程就會越少。

      公式有了,但是又缺少線程的時間,執行時間和等待時間我該從哪去獲取呢?那么這個就需要我們去借用一些工具了,想要獲取到準確的時間,就需要進行壓測,然后監控JVM的線程情況以及CPU的負載情況。最后得到他們的時間,然后合理充分的利用資源。

      配置參數標準

      了解了線程場景后,我們再來看一下,如何通過我們需要的應用場景來設置對于的線程池初始參數。

      核心線程數和最大線程數

      上面我們說到過,設置合理的線程數,需要看線程的使用場景是CPU密集型任務還是耗時IO型任務。
      核心線程數的設置量就按照上面的公式來計算

      • CPU密集型任務:最大線程數為核心線程數的1~2倍
      • 耗時IO型任務:最大線程數為核心線程數的2~5倍(依場景來設定)

      那么有沒有通用的設置方法,就是可以適用于CPU密集型任務和耗時IO型任務都適用的設置方法。如果想設置這樣的線程,核心線程數不變,但是最大線程數可以設置的稍微大一點,一般為核心線程數的3~4倍。這種是常用方法,只有在你沒有對線程性能進行壓測的情況下進行設置,如果想獲取最準確的,還是以壓測后的線程狀態,依情況來合理設置。

      阻塞隊列

      之前我們有介紹過LinkedBlockingQueue,SynchronousQueue,DelayedWorkQueue這三種隊列,具體可以參考
      常用的三種阻塞隊列這篇文章,這三種隊列其實都有一個缺點,那就是不好控制線程的的最大數量,這樣可能會導致出現因為隊列中的線程任務太多導致內存爆滿爆出OOM異常。為了避免這種情況,我們再平時設置自己的線程時,都回去使用ArrayBlockingQueue這個阻塞隊列,這個阻塞隊列唯一的好處就是,他可以設置隊列的大小,并且隊列滿了之后,他也不會將塞不進來的線程任務拋棄,而是會阻塞著,然后根據線程池設置的拒絕策略來執行,這樣也就避免了丟失線程任務的風險。那么根據使用場景,我們該如何去設置隊列的容量呢?如果我們使用容量更大的隊列和更小的線程數,就可以減少上下文切換帶來的開銷,但也可能會因此降低整體的吞吐量,如果我們的任務是IO密集型,則可以選擇稍小容量的隊列和更大的最大線程數,這樣整體的線程效率就會高,不過也會帶來更大的上下文切換。我們知道了這個東西之后,其實會發現設置多大的隊列大小,并沒有一個準確的公式,而是慢慢的業務運行的時候慢慢的試錯,當發現我們的容量設置的并不理想,則需要依照當時的情況來調整。

      線程工廠

      線程工廠的作用其實就是創建線程,如果你對線程池的默認創建線程的方式不滿意,想要對線程池里面的線程名字修改,或者在創建線程的時候去執行一些前置任務,這個時候你就可以自己創建一個線程工廠,示例代碼如下。

      public class TestThreadFactory implements ThreadFactory {
      
          private static AtomicInteger atomicInteger = new AtomicInteger();
      
          @Override
          public Thread newThread(Runnable r) {
              atomicInteger.addAndGet(1);
              return new Thread(r,"自定義名字-"+atomicInteger.get());
          }
      }
      

      拒絕策略

      拒絕策略目前有四種,AbortPolicy,DiscardPolicy,DiscardOldestPolicy 或者 CallerRunsPolicy。詳細的作用我們就不說了,可以移步到線程池的4種拒絕策略這篇文章中查看,按照自己的需求來使用合適的拒絕策略,當然,如果你不滿足這四種線程策略,想要自己去整活,線程池也會給你機會,這時你就可以通過實現RejectedExecutionHandler類來實現自己的拒絕策略,示例代碼如下。

      public class MyRejectPolicy implements RejectedExecutionHandler {
          @Override
          public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
              System.out.println("被拒絕了");
          }
      }
      

      總結

      說了這么多,大家可能會發現,其實線程池的創建與配置,并沒有一個統一的標準,文章中給出的一些公式,其實僅僅供于在第一次創建線程池的時候的配置,如果到后面發現,當先創建的線程規則不滿足于現狀,其實這個時候你就可以以自己看到的狀況來定,比如線程執行的時間過長,并且很占用時間,但又不消耗CPU資源,這個時候其實你就會覺得我可以吧最大線程池擴大一點,相反遇到線程執行很慢,并且同時執行的線程又很多,這個時候可能就是遇到了CPU密集執行的情況,這時就可以將最大線程數調小一點,線程的隊列容量再調大一點。這樣下來,可能就會有不一樣的效果。

      posted @ 2022-01-29 15:19  鄧小白  閱讀(1961)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 无码中文字幕av免费放| 2019国产精品青青草原| 人妻精品动漫h无码| 亚洲日韩精品无码一区二区三区 | 我国产码在线观看av哈哈哈网站| 日本精品aⅴ一区二区三区| 国产香蕉尹人在线视频你懂的| 国产免费毛卡片| 又黄又爽又色的少妇毛片| 国产精品中出一区二区三区| 欧美日韩精品一区二区三区高清视频 | 亚洲色最新高清AV网站| 久热视频这里只有精品6| 亚洲一区二区三上悠亚| 日韩精品人妻中文字幕| 久久精品亚洲精品国产色婷| 亚洲一二区在线视频播放| 日本熟妇hdsex视频| 鲁一鲁一鲁一鲁一澡| 国产精品美女一区二三区| 国产精品中文字幕视频| 免费看视频的网站| 国产三级精品三级在线观看| 被黑人巨大一区二区三区| 狠狠色噜噜狠狠狠狠色综合久| 国产精品自拍午夜福利| 中文字幕乱妇无码AV在线| 18禁网站免费无遮挡无码中文| 午夜男女爽爽影院在线| 久9re热视频这里只有精品免费| 最新国产AV最新国产在钱| 无套内内射视频网站| 精品偷拍一区二区三区| 国产一区二区在线有码| 青草青草视频2免费观看| 亚洲综合一区二区精品导航| 嗯灬啊灬把腿张开灬动态图| 少妇伦子伦精品无吗| 国产成人精品a视频| 国产精品成人午夜久久| 中国老妇xxxx性开放|