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

          Java線程池創(chuàng)建方式,原來是這樣的!

          共 4047字,需瀏覽 9分鐘

           ·

          2021-10-08 23:00

          來源:blog.csdn.net/dabusiGin/

          article/details/105327873

          Executor是不建議的

          Executors類為我們提供了各種類型的線程池,經常使用的工廠方法有:

          public?static?ExecutorService?newSingleThreadExecutor()
          public?static?ExecutorService?newFixedThreadPool(int?nThreads)
          public?static?ExecutorService?newCachedThreadPool()
          public?static?ScheduledExecutorService?newSingleThreadScheduledExecutor()
          public?static?ScheduledExecutorService?newScheduledThreadPool(int?corePoolSize)

          書寫一段很簡單的測試代碼:

          public?class?ThreadDemo?{
          ?public?static?void?main(String[]?args)?{
          ??ExecutorService?es?=?Executors.newSingleThreadExecutor();
          ?}
          }

          當我們用阿里巴巴的P3C檢查代碼時,會被教育的!!!!

          阿里爸爸是不允許這么創(chuàng)建線程池的,上面的警告寫的很明確“線程池不允許使用Executors去創(chuàng)建,而是通過ThreadPoolExecutor的方式,這樣的處理方式讓寫的同學更加明確線程池的運行規(guī)則,規(guī)避資源耗盡的風險。”(PS:很難得在編譯器中看到中文提示,對于英語不好的同學來說,簡直是福音,喜極而泣!!!!)

          強制使用ThreadPoolExecutor

          我們使用ThreadPoolExecutor創(chuàng)建線程池:

          public?class?ThreadDemo?{
          ?public?static?void?main(String[]?args)?{
          ??ExecutorService?es?=?new?ThreadPoolExecutor(1,?1,?0L,?TimeUnit.MILLISECONDS,
          ????new?LinkedBlockingQueue(10),?Executors.defaultThreadFactory(),
          ????new?ThreadPoolExecutor.DiscardPolicy());
          ?}
          }

          此時,再用P3C檢查代碼,終于沒有報錯了。

          在華麗的分隔符之后,我們還是有必要從JDK源碼的層面深挖一下其中的原理。

          首先是靜態(tài)方法newSingleThreadExecutor()newFixedThreadPool(int nThreads)newCachedThreadPool()。我們來看一下其源碼實現(基于JDK8)。

          public?static?ExecutorService?newSingleThreadExecutor()?{
          ????????return?new?FinalizableDelegatedExecutorService
          ????????????(new?ThreadPoolExecutor(1,?1,
          ????????????????????????????????????0L,?TimeUnit.MILLISECONDS,
          ????????????????????????????????????new?LinkedBlockingQueue()));
          }

          public?static?ExecutorService?newFixedThreadPool(int?nThreads)?{
          ????????return?new?ThreadPoolExecutor(nThreads,?nThreads,
          ??????????????????????????????????????0L,?TimeUnit.MILLISECONDS,
          ??????????????????????????????????????new?LinkedBlockingQueue());
          }

          public?static?ExecutorService?newCachedThreadPool()?{
          ????????return?new?ThreadPoolExecutor(0,?Integer.MAX_VALUE,
          ??????????????????????????????????????60L,?TimeUnit.SECONDS,
          ??????????????????????????????????????new?SynchronousQueue());
          }

          通過查看源碼我們知道上述三種靜態(tài)方法的內部實現均使用了ThreadPoolExecutor類。難怪阿里爸爸會建議通過ThreadPoolExecutor的方式實現,原來Executors類的靜態(tài)方法也是用的它,只不過幫我們配了一些參數而已。

          第二是ThreadPoolExecutor類的構造方法。既然現在要直接使用ThreadPoolExecutor類了,那么其中的初始化參數就要我們自己配了,了解其構造方法勢在必行。

          ThreadPoolExecutor類一共有四個構造方法,我們只需要了解之中的一個就可以了,因為其他三種構造方法只是幫我們配置了一些默認參數,最后還是調用了它。

          public?ThreadPoolExecutor(int?corePoolSize,
          ????????????int?maximumPoolSize,
          ????????????long?keepAliveTime,
          ????????????TimeUnit?unit,
          ????????????BlockingQueue?workQueue,
          ????????????ThreadFactory?threadFactory,
          ????????????RejectedExecutionHandler?handler)

          其中的參數含義是:

          • corePoolSize:線程池中的線程數量;
          • maximumPoolSize:線程池中的最大線程數量;
          • keepAliveTime:當線程池線程數量超過corePoolSize時,多余的空閑線程會在多長時間內被銷毀;
          • unit:keepAliveTime的時間單位;
          • workQueue:任務隊列,被提交但是尚未被執(zhí)行的任務;
          • threadFactory:線程工廠,用于創(chuàng)建線程,一般情況下使用默認的,即Executors類的靜態(tài)方法defaultThreadFactory();handler:拒絕策略。當任務太多來不及處理時,如何拒絕任務。

          對于這些參數要有以下了解:

          corePoolSize與maximumPoolSize的關系

          首先corePoolSize肯定是 <= maximumPoolSize。

          其他關系如下:

          • 若當前線程池中線程數 < corePoolSize,則每來一個任務就創(chuàng)建一個線程去執(zhí)行;
          • 若當前線程池中線程數 >= corePoolSize,會嘗試將任務添加到任務隊列。如果添加成功,則任務會等待空閑線程將其取出并執(zhí)行;
          • 若隊列已滿,且當前線程池中線程數 < maximumPoolSize,創(chuàng)建新的線程;
          • 若當前線程池中線程數 >= maximumPoolSize,則會采用拒絕策略(JDK提供了四種,下面會介紹到)。

          注意:關系3是針對的有界隊列,無界隊列永遠都不會滿,所以只有前2種關系。

          學習資料:Java進階視頻資源

          workQueue

          參數workQueue是指提交但未執(zhí)行的任務隊列。若當前線程池中線程數>=corePoolSize時,就會嘗試將任務添加到任務隊列中。主要有以下幾種:

          • SynchronousQueue:直接提交隊列。SynchronousQueue沒有容量,所以實際上提交的任務不會被添加到任務隊列,總是將新任務提交給線程執(zhí)行,如果沒有空閑的線程,則嘗試創(chuàng)建新的線程,如果線程數量已經達到最大值(maximumPoolSize),則執(zhí)行拒絕策略。
          • LinkedBlockingQueue:無界的任務隊列。當有新的任務來到時,若系統的線程數小于corePoolSize,線程池會創(chuàng)建新的線程執(zhí)行任務;當系統的線程數量等于corePoolSize后,因為是無界的任務隊列,總是能成功將任務添加到任務隊列中,所以線程數量不再增加。若任務創(chuàng)建的速度遠大于任務處理的速度,無界隊列會快速增長,直到內存耗盡。

          handler

          JDK內置了四種拒絕策略:

          • DiscardOldestPolicy策略:丟棄任務隊列中最早添加的任務,并嘗試提交當前任務;
          • CallerRunsPolicy策略:調用主線程執(zhí)行被拒絕的任務,這提供了一種簡單的反饋控制機制,將降低新任務的提交速度。
          • DiscardPolicy策略:默默丟棄無法處理的任務,不予任何處理。
          • AbortPolicy策略:直接拋出異常,阻止系統正常工作。

          至此,我們直接new ThreadPoolExecutor類就不用慌了!!!!


          推薦閱讀

          一鍵生成Springboot & Vue項目!【畢設神器】



          END


          順便給大家推薦一個GitHub項目,這個 GitHub 整理了上千本常用技術PDF,絕大部分核心的技術書籍都可以在這里找到,

          GitHub地址:https://github.com/javadevbooks/books

          Gitee地址:https://gitee.com/javadevbooks/books

          電子書已經更新好了,你們需要的可以自行下載了,記得點一個star,持續(xù)更新中..



          瀏覽 40
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  中文字幕综合在线观看 | 色欲天香天天免费视频 | 成人午夜性爱视频 | 老鸭窝国产 | 日本无码中文字幕在线视频公司 |