日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java线程池ThreadPoolExecutor

發(fā)布時(shí)間:2023/12/15 java 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java线程池ThreadPoolExecutor 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>

本文首發(fā)于個(gè)人微信公眾號(hào)《andyqian》, 關(guān)注免費(fèi)獲取Java學(xué)習(xí)資料

前言

??多線程一直是Java進(jìn)階的必修課。在Java中,我們很早就知道可以通過 Thread 類和 Runnable 接口來實(shí)現(xiàn)多線程。與之有著類似職責(zé)的數(shù)據(jù)庫連接,也可通過JDBC創(chuàng)建與使用。但我們深知無論是數(shù)據(jù)庫連接的創(chuàng)建與銷毀,還是線程的創(chuàng)建與銷毀,都是一件及其消耗性能的事情。為了減少這種情況的發(fā)生,前輩們就在思考,是不是可以復(fù)用已有的數(shù)據(jù)庫連接?減少創(chuàng)建,銷毀動(dòng)作?這就是后來數(shù)據(jù)庫連接池的由來。同樣的,為了復(fù)用線程,也就有了線程池。我一直獨(dú)自暗喜,身為一位幸福的Java程序員,前有Java虛擬機(jī)管理內(nèi)存,后有Doug Lea 大師提供并發(fā)庫,鎖機(jī)制。簡直幸福的不像話,不過幸福歸幸福,該掌握的還是需要掌握的,我們一起來看看今天的主角:ThreadPoolExecutor。

簡介

??在面試過程中,也時(shí)常會(huì)遇到一些關(guān)于線程池的問題,例如:

  • 線程池中核心參數(shù)有哪些?

  • 有沒有自己實(shí)現(xiàn)過線程池?

  • 如果讓你自己實(shí)現(xiàn)線程池,你會(huì)怎么做?

  • 這些問題,其實(shí)考核的就是Java線程池的知識(shí),更具體一點(diǎn)就是對(duì)ThreadPoolExector類熟不熟悉,下面代碼是ThreadPoolExector類的全參構(gòu)造函數(shù)。下面我們就一一對(duì)參數(shù)進(jìn)行了解。

    public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,ThreadFactory threadFactory,RejectedExecutionHandler handler) {if (corePoolSize < 0 ||maximumPoolSize <= 0 ||maximumPoolSize < corePoolSize ||keepAliveTime < 0)throw new IllegalArgumentException();if (workQueue == null || threadFactory == null || handler == null)throw new NullPointerException();this.corePoolSize = corePoolSize;this.maximumPoolSize = maximumPoolSize;this.workQueue = workQueue;this.keepAliveTime = unit.toNanos(keepAliveTime);this.threadFactory = threadFactory;this.handler = handler;}

    其中:

  • corePoolSize:表示該線程池最小的工作線程數(shù)。默認(rèn)情況下,當(dāng)需要使用時(shí)創(chuàng)建線程,也可以調(diào)用 prestartAllCoreThreads() 方法進(jìn)行預(yù)創(chuàng)建所有的核心線程。

  • maximumPoolSize:表示該線程池最大的線程數(shù)量,理論上將其設(shè)置為無限大,就會(huì)創(chuàng)建無限多的線程,當(dāng)然,創(chuàng)建線程的數(shù)量最終由系統(tǒng)資源也就是操作系統(tǒng)決定。

  • keepAliveTime:表示空閑線程的超時(shí)時(shí)間,(單位為納秒)。但在構(gòu)造函數(shù)中,單位與unit 參數(shù)配合使用,最終轉(zhuǎn)換為納秒。

  • unit:表示空閑線程超時(shí)的時(shí)間單位,可選值有:java.util.concurrent.TimeUnit中的值,SECONDS(秒),MINUTES(分),HOURS(小時(shí)),DAYS(天) 等。

  • workQueue :表示工作隊(duì)列(其實(shí)是一個(gè)runnable隊(duì)列,在線程池中定義為Worker),其基類為:java.util.concurrent.BlockingQueue。

  • threadFactory:線程工廠,通常用于創(chuàng)建線程,以及命令規(guī)則。默認(rèn)為: Executors.defaultThreadFactory()。

  • handler 表示處理策略,當(dāng)workQueue隊(duì)列滿時(shí),以及創(chuàng)建線程錯(cuò)誤時(shí)的處理策略。其基類為 java.util.concurrent.RejectedExecutionHandler。默認(rèn)為:AbortPolicy 策略。

  • 不同組合

    ??在 java.util.concurrent.Executors類為我們提供了多種組合,其底層還是調(diào)用ThreadPoolExecutor。下面列舉幾個(gè)常用的方法:

    1.?newFixedThreadPool

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

    特性:線程數(shù)量大小固定,且 corePoolSize 與 maximumPoolSize 數(shù)量相等。當(dāng)線程數(shù)量設(shè)置太少時(shí)。task則會(huì)積壓在LinkedBlockingQueue隊(duì)列中。當(dāng) task 任務(wù)大于Integer.MAX_VALUE時(shí) 則會(huì)有OOM發(fā)生的風(fēng)與之類是的還有newSingleThreadExecutor方法。

    2. newCachedThreadPool

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

    特性:corePoolSize數(shù)量為0,maximumPoolSize數(shù)量為Integer.MAX_VALUE,也就是說理論上是可以創(chuàng)建Integer.MAX_VALUE個(gè)線程的。keepAiveTime時(shí)間為 60秒。BlockingQueue使用的是SynchronousQueue,由于其沒用容量,意味這每一次put對(duì)應(yīng)著一次take操作,其吞吐量比較高。正因?yàn)槿绱?#xff0c;當(dāng)task到達(dá)一定程度時(shí),可能會(huì)創(chuàng)建許多線程,從而導(dǎo)致OOM,甚至服務(wù)不可用。

    ?

    上述方法其實(shí)是對(duì)ThreadPoolExecutor方法的封裝對(duì)不對(duì),知道了ThreadPoolExecutor的每一個(gè)參數(shù),再來使用這個(gè),就得心應(yīng)手了對(duì)不對(duì)。

    規(guī)范

    Executors類這么方便,是不是可以直接使用Executors類來創(chuàng)建呢?當(dāng)然可以,但并不建議這樣做。在《阿里Java手冊(cè)》中的并發(fā)處理小節(jié)中有提到:

    【強(qiáng)制】線程池不允許使用 Executors 去創(chuàng)建,而是通過 ThreadPoolExecutor 的方式,這樣的處理方式可以讓寫的同學(xué)更加明確線程池的運(yùn)行規(guī)則,規(guī)避資源耗盡的風(fēng)險(xiǎn)。

    說明:Executors 返回的線程池對(duì)象的弊端如下:
    1) FixedThreadPool 和 SingleThreadPool :
    允許的請(qǐng)求隊(duì)列長度為 Integer.MAX_VALUE,可能會(huì)堆積大量的請(qǐng)求,從而導(dǎo)致 OOM 。
    2) CachedThreadPool 和 ScheduledThreadPool :允許的創(chuàng)建線程數(shù)量為 Integer.MAX_VALUE ,可能會(huì)創(chuàng)建大量的線程,從而導(dǎo)致 OOM 。

    在實(shí)際應(yīng)用中,我們應(yīng)該遵守規(guī)范,避免掉一些沒必要的問題。該規(guī)約其最終目的是讓大家能夠更清楚了解線程池的每個(gè)參數(shù),從而達(dá)到能夠在實(shí)際應(yīng)用場景中調(diào)為最優(yōu)組合使用,使其達(dá)到最大性能。同樣的,我們也通過安裝阿里巴巴的規(guī)約插件進(jìn)行自動(dòng)掃描與提醒。在Idea中 File -> Setings -> Plugins -> Browse repositories中搜索『Alibaba Java Coding Guidelines』安裝即可!

    小結(jié)

    在這篇文章中,算是對(duì)ThreadPoolExector的一個(gè)初步了解。知道了其核心參數(shù),到底是怎么回事。但這還并不夠,且不足以學(xué)以致用,還有很多疑問,如:

  • ThreadPoolExecutor的原理是怎樣的?

  • 我們?nèi)绾巫远x一個(gè)線程池?

  • ThreadPoolExecutor在Dubbo中的實(shí)踐

  • 這些疑惑都需要一一去揭曉。由于篇幅原因,這些會(huì)作為好幾篇文章進(jìn)行記錄。其目的是能夠?qū)W以致用,面試時(shí)也能得心應(yīng)手。


    ?

    相關(guān)閱讀:

    《使用 Mybatis 真心不要偷懶!》

    《再談Java 生產(chǎn)神器 BTrace》

    《Java 生產(chǎn)神器 ?BTrace》

    《重構(gòu)不完全指南!》


    ?

    如果想深入學(xué)習(xí)Java并發(fā)編程,《Java并發(fā)編程的藝術(shù)》這本書是值得閱讀的。當(dāng)然了,如果你讀喜歡電子書,也可以回復(fù)公眾號(hào)消息『Java并發(fā)編程的藝術(shù)』進(jìn)行免費(fèi)獲取!

    ?

    關(guān)注免費(fèi)獲取Java學(xué)習(xí)資料

    轉(zhuǎn)載于:https://my.oschina.net/u/1462914/blog/3049668

    總結(jié)

    以上是生活随笔為你收集整理的Java线程池ThreadPoolExecutor的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。