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

          阿里巴巴建議的線(xiàn)程池創(chuàng)建方式,你用上了嗎?

          共 4042字,需瀏覽 9分鐘

           ·

          2021-10-16 09:20

          點(diǎn)擊下方“IT牧場(chǎng)”,選擇“設(shè)為星標(biāo)”

          來(lái)源:blog.csdn.net/dabusiGin/

          article/details/105327873

          Executor是不建議的

          Executors類(lèi)為我們提供了各種類(lèi)型的線(xiàn)程池,經(jīng)常使用的工廠方法有:

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

          書(shū)寫(xiě)一段很簡(jiǎn)單的測(cè)試代碼:

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

          當(dāng)我們用阿里巴巴的P3C檢查代碼時(shí),會(huì)被教育的!!!!

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

          強(qiáng)制使用ThreadPoolExecutor

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

          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());
          ?}
          }

          此時(shí),再用P3C檢查代碼,終于沒(méi)有報(bào)錯(cuò)了。

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

          首先是靜態(tài)方法newSingleThreadExecutor()newFixedThreadPool(int nThreads)newCachedThreadPool()。我們來(lái)看一下其源碼實(shí)現(xiàn)(基于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());
          }

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

          第二是ThreadPoolExecutor類(lèi)的構(gòu)造方法。既然現(xiàn)在要直接使用ThreadPoolExecutor類(lèi)了,那么其中的初始化參數(shù)就要我們自己配了,了解其構(gòu)造方法勢(shì)在必行。

          ThreadPoolExecutor類(lèi)一共有四個(gè)構(gòu)造方法,我們只需要了解之中的一個(gè)就可以了,因?yàn)槠渌N構(gòu)造方法只是幫我們配置了一些默認(rèn)參數(shù),最后還是調(diào)用了它。

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

          其中的參數(shù)含義是:

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

          對(duì)于這些參數(shù)要有以下了解:

          corePoolSize與maximumPoolSize的關(guān)系

          首先corePoolSize肯定是 <= maximumPoolSize。

          其他關(guān)系如下:

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

          注意:關(guān)系3是針對(duì)的有界隊(duì)列,無(wú)界隊(duì)列永遠(yuǎn)都不會(huì)滿(mǎn),所以只有前2種關(guān)系。

          workQueue

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

          • SynchronousQueue:直接提交隊(duì)列。SynchronousQueue沒(méi)有容量,所以實(shí)際上提交的任務(wù)不會(huì)被添加到任務(wù)隊(duì)列,總是將新任務(wù)提交給線(xiàn)程執(zhí)行,如果沒(méi)有空閑的線(xiàn)程,則嘗試創(chuàng)建新的線(xiàn)程,如果線(xiàn)程數(shù)量已經(jīng)達(dá)到最大值(maximumPoolSize),則執(zhí)行拒絕策略。
          • LinkedBlockingQueue:無(wú)界的任務(wù)隊(duì)列。當(dāng)有新的任務(wù)來(lái)到時(shí),若系統(tǒng)的線(xiàn)程數(shù)小于corePoolSize,線(xiàn)程池會(huì)創(chuàng)建新的線(xiàn)程執(zhí)行任務(wù);當(dāng)系統(tǒng)的線(xiàn)程數(shù)量等于corePoolSize后,因?yàn)槭菬o(wú)界的任務(wù)隊(duì)列,總是能成功將任務(wù)添加到任務(wù)隊(duì)列中,所以線(xiàn)程數(shù)量不再增加。若任務(wù)創(chuàng)建的速度遠(yuǎn)大于任務(wù)處理的速度,無(wú)界隊(duì)列會(huì)快速增長(zhǎng),直到內(nèi)存耗盡。

          handler

          JDK內(nèi)置了四種拒絕策略:

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

          至此,我們直接new ThreadPoolExecutor類(lèi)就不用慌了!!!!

          干貨分享

          最近將個(gè)人學(xué)習(xí)筆記整理成冊(cè),使用PDF分享。關(guān)注我,回復(fù)如下代碼,即可獲得百度盤(pán)地址,無(wú)套路領(lǐng)取!

          ?001:《Java并發(fā)與高并發(fā)解決方案》學(xué)習(xí)筆記;?002:《深入JVM內(nèi)核——原理、診斷與優(yōu)化》學(xué)習(xí)筆記;?003:《Java面試寶典》?004:《Docker開(kāi)源書(shū)》?005:《Kubernetes開(kāi)源書(shū)》?006:《DDD速成(領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)速成)》?007:全部?008:加技術(shù)群討論

          加個(gè)關(guān)注不迷路

          喜歡就點(diǎn)個(gè)"在看"唄^_^

          瀏覽 17
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  SM在线免费观看 | 亚洲AV无码久久精品蜜桃动态图 | 俺来也久草国产在线视频 | 人人艹人人搡 | 久久黄色免费 |