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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

java并发之线程池

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

文章目錄

    • @[TOC]
    • 1:ThreadPoolExcutor
      • (1):ThreadPoolExcutor構(gòu)造函數(shù)
      • (2):構(gòu)造函數(shù)的參數(shù)
      • (3):圖示 核心線程數(shù) 最大線程數(shù) 阻塞隊(duì)列
      • (4):一個(gè)任務(wù)在線程池的流程
    • 2:固定容量的線程池(newFixedThreadPool)
      • (1):構(gòu)造函數(shù)
      • (2):特點(diǎn)
      • (3):代碼示例
    • 3:可緩存的線程池
      • (1):構(gòu)造函數(shù)
      • (2):特點(diǎn)
    • 4:單線程池
      • (1):構(gòu)造函數(shù)
      • (2):特點(diǎn)
    • 5:固定數(shù)量線程池...和ThreadPoolExecutor的區(qū)別聯(lián)系
      • (1)如何創(chuàng)建固定數(shù)量的線程池,可緩存的線程池,單線程池
      • (2)和ThreadPoolExcutor的聯(lián)系
    • 5:自定義線程池
      • (1):自定義線程池的規(guī)則
      • (2):關(guān)于線程池的 Executor工具類的execute()方法
      • (3):代碼示例
      • (4):關(guān)于拒絕策略
    • 6:關(guān)閉線程池

1:ThreadPoolExcutor

(1):ThreadPoolExcutor構(gòu)造函數(shù)

public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue<Runnable> workQueue,RejectedExecutionHandler handler) {this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,Executors.defaultThreadFactory(), handler);}

(2):構(gòu)造函數(shù)的參數(shù)

  • corePoolSize核心線程數(shù)目(最多保留的線程數(shù))
  • maximumPoolSize最大線程數(shù)目
  • keepAliveTime生存時(shí)間-針對(duì)救急線程
  • unit時(shí)間單位-針對(duì)救急線程
  • workQueue阻塞隊(duì)列
  • threadFactory線程工廠-可以為線程創(chuàng)建時(shí)起個(gè)好名字
  • handler拒絕策略

(3):圖示 核心線程數(shù) 最大線程數(shù) 阻塞隊(duì)列

  • 核心線程數(shù)就是我們銀行一直正常開的窗口
  • 阻塞隊(duì)列就是銀行常用窗口人數(shù)滿了,然后就在后候客區(qū)等待的顧客
  • 救急線程就是阻塞隊(duì)列滿了 不得不再開幾個(gè)營(yíng)業(yè)窗口
  • 最大線程數(shù)目 = 救急線程數(shù)目 + 核心線程數(shù)目

(4):一個(gè)任務(wù)在線程池的流程

  • 線程池中剛開始沒有線程,當(dāng)一個(gè)任務(wù)提交給線程池后,線程池會(huì)創(chuàng)建一個(gè)新線程來執(zhí)行任務(wù)。
  • 當(dāng)線程數(shù)達(dá)到corePoolSize并沒有線程空閑,這時(shí)再加入任務(wù),新加的任務(wù)會(huì)被加入workQueue隊(duì)列排
    隊(duì),直到有空閑的線程。
  • 如果隊(duì)列選擇了有界隊(duì)列,那么任務(wù)超過了隊(duì)列大小時(shí),會(huì)創(chuàng)建maximumPoolSize-corePoolSize數(shù)目的
    線程來救急。
  • 如果線程到達(dá)maximumPoolSize仍然有新任務(wù)這時(shí)會(huì)執(zhí)行拒絕策略。拒絕策略jd提供了4種實(shí)現(xiàn),其它
    著名框架也提供了實(shí)現(xiàn)
    • AbortPolicy讓調(diào)用者拋出RejectedExecutionException異常,這是默認(rèn)策略
    • CallerRunsPolicy讓調(diào)用者運(yùn)行任務(wù)
    • DiscardPolicy放棄本次任務(wù)
    • DiscardOldestPolicy放棄隊(duì)列中最早的任務(wù),本任務(wù)取而代之
    • Dubbo的實(shí)現(xiàn),在拋出RejectedExecutionException異常之前會(huì)記錄日志,并dump線程棧信息,方便定
      位問題
    • Netty的實(shí)現(xiàn),是創(chuàng)建一個(gè)新線程來執(zhí)行任務(wù)
    • ActiveMQ的實(shí)現(xiàn),帶超時(shí)等待(60s)嘗試放入隊(duì)列,類似我們之前自定義的拒絕策略
    • PinPoint的實(shí)現(xiàn),它使用了一個(gè)拒絕策略鏈,會(huì)逐一嘗試策略鏈中每種拒絕策略
    • 當(dāng)高峰過去后,超過corePoolSize的救急線程如果一段時(shí)間沒有任務(wù)做,需要結(jié)束節(jié)省資源,這個(gè)時(shí)間由
  • keepAliveTime和unit來控制。

2:固定容量的線程池(newFixedThreadPool)

(1):構(gòu)造函數(shù)

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

(2):特點(diǎn)

  • 核心線程數(shù)==最大線程數(shù)
    (沒有救急線程被創(chuàng)建),因此也無(wú)需超時(shí)時(shí)間
  • 阻塞隊(duì)列是無(wú)界的,可以放任意數(shù)量的任務(wù)
  • 評(píng)價(jià)
    適用于任務(wù)量已知,相對(duì)耗時(shí)的任務(wù)

(3):代碼示例

public class text02 {public static void main(String[] args) {ExecutorService executorService1 = Executors.newFixedThreadPool(2);//固定線程數(shù) 核心線程數(shù) == 最大線程數(shù) 無(wú)救急線程 并且線程不會(huì)關(guān)閉//線程池里開啟一個(gè)線程 并執(zhí)行一個(gè)任務(wù)executorService1.execute(() -> {System.out.println(Thread.currentThread().getName() + "->1");});//線程池再開啟一個(gè)線程 并執(zhí)行一個(gè)任務(wù)executorService1.execute(() -> {System.out.println(Thread.currentThread().getName() + "->2");});//此時(shí)又來了一個(gè)任務(wù),因?yàn)榍懊娴娜蝿?wù)執(zhí)行時(shí)間比較短,所以再來任務(wù)的話,不會(huì)進(jìn)入阻塞隊(duì)列//而是會(huì)用前面已經(jīng)開啟的線程繼續(xù)執(zhí)行任務(wù)executorService1.execute(()-> {System.out.println(Thread.currentThread().getName()+"->3");});} }

3:可緩存的線程池

(1):構(gòu)造函數(shù)

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

(2):特點(diǎn)

  • 核心線程數(shù)為0,最大線程數(shù)為Interger.MAX_VALUE,救急線程的空閑存活時(shí)間是60s
    • 沒有核心線程 全部都是救急線程
    • 救急線程可以無(wú)線創(chuàng)建
  • 隊(duì)列采用了SynchronousQueue實(shí)現(xiàn)特點(diǎn)是,它沒有容量,沒有線程來取是放不進(jìn)去的(一手交錢、一手
    交貨)
  • 評(píng)價(jià)
    整個(gè)線程池表現(xiàn)為線程數(shù)會(huì)根據(jù)任務(wù)量不斷增長(zhǎng),沒有上限,當(dāng)任務(wù)執(zhí)行完畢,空閑1分鐘后釋放線
    程。==適合任務(wù)數(shù)處比較密集,但每個(gè)任務(wù)執(zhí)行時(shí)間較短的情況 ==(如果任務(wù)時(shí)間比較長(zhǎng),那么就會(huì)不斷創(chuàng)建線程,消耗系統(tǒng)性能)

4:單線程池

(1):構(gòu)造函數(shù)

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

(2):特點(diǎn)

  • 核心線程數(shù)為1,最大線程數(shù)也為1,這個(gè)線程一直存活,不會(huì)釋放
  • 隊(duì)列是無(wú)界隊(duì)列,當(dāng)任務(wù)數(shù)目大于1的時(shí)候,任務(wù)會(huì)被放入無(wú)界隊(duì)列
  • 和普通單線程的區(qū)別
    自己創(chuàng)建一個(gè)單線程串行執(zhí)行任務(wù),如果任務(wù)執(zhí)行失敗而終止那么沒有任何補(bǔ)救措施,而線程池還會(huì)新建
    一個(gè)線程,保證池的正常工作
  • 和固定容量的線程池只開辟一個(gè)線程的區(qū)別
    Executors…newSingleThreadExecutor()線程個(gè)數(shù)始終為1,不能修改
    FinalizableDelegatedExecutorService應(yīng)用的是裝飾器模式,只對(duì)外暴露了ExecutorService接口,因此不
    能調(diào)用ThreadPoolExecutor中特有的方法
    Executors.newFixedThreadPool(1)初始時(shí)為l,以后還可以修改
    對(duì)外暴露的是ThreadPoolExecutor對(duì)象,可以強(qiáng)轉(zhuǎn)后調(diào)用setCorePoolSize等方法進(jìn)行修改

5:固定數(shù)量線程池…和ThreadPoolExecutor的區(qū)別聯(lián)系

(1)如何創(chuàng)建固定數(shù)量的線程池,可緩存的線程池,單線程池

ExecutorService executorService1 = Executors.newFixedThreadPool(5);ExecutorService executorService2 = Executors.newSingleThreadExecutor();ExecutorService executorService3 = Executors.newCachedThreadPool();

(2)和ThreadPoolExcutor的聯(lián)系

我們將對(duì)應(yīng)的線程池點(diǎn)進(jìn)去,發(fā)現(xiàn)其實(shí)底層還是靠ThreadPoolExcutors來實(shí)現(xiàn)

5:自定義線程池

(1):自定義線程池的規(guī)則

我們采用 ThreadPoolExcutors來創(chuàng)建,這使阿里爸爸開發(fā)手冊(cè)中明文推薦的,主要是其他線程池實(shí)現(xiàn)類都有OOM(內(nèi)存用完了)的風(fēng)險(xiǎn)

(2):關(guān)于線程池的 Executor工具類的execute()方法

  • 當(dāng)有新的任務(wù)要處理時(shí),先看線程池中的線程數(shù)量是否大于corePoolSize,再看緩沖隊(duì)列workQueue是否滿,最后看線程池 中的線程數(shù)量是否大于maximumPoolSize
    另外,當(dāng)線程池中的線程數(shù)量大于corePoolSize時(shí),如果里面有線程的空閑時(shí)間超過了keepAliveTime,就將其移除線程池
  • 也就是excutor()方法中會(huì)創(chuàng)建線程執(zhí)行任務(wù),但是這個(gè)線程的數(shù)量是有限的,雖然數(shù)量有限,但是核心線程可以重復(fù)執(zhí)行任務(wù),救急線程在空閑存活時(shí)間的里也可以執(zhí)行任務(wù)

(3):代碼示例

public class text03 {public static void main(String[] args) {Executors.newCachedThreadPool();ThreadPoolExecutor pool = new ThreadPoolExecutor(2,//核心線程數(shù)5,//最大線程數(shù) = 核心線程數(shù) + 救急線程數(shù)(當(dāng)阻塞隊(duì)列)3,//救濟(jì)線程的空閑存活時(shí)間TimeUnit.MINUTES,//時(shí)間的單位new LinkedBlockingQueue<>(3),//阻塞隊(duì)列默認(rèn)為無(wú)界隊(duì)列但是我將其設(shè)置為3Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy()//拒絕策略,一旦超過最大線程數(shù)就拋異常);//我們?cè)谝粋€(gè)for循環(huán)內(nèi)//當(dāng)我們同時(shí)來了9個(gè)任務(wù)的時(shí)候,會(huì)有2個(gè)任務(wù)去核心線程去執(zhí)行,還有3個(gè)任務(wù)進(jìn)入阻塞隊(duì)列,還有3個(gè)任務(wù)會(huì)去救急線程那去執(zhí)行//那么我們的還有一個(gè)線程無(wú)法執(zhí)行,此時(shí)會(huì)采取拒絕策略 ;//我們阻塞隊(duì)列中的任務(wù)是等著 救急線程 或者 核心線程去執(zhí)行完手里的任務(wù)去執(zhí)行的for (int i = 1; i <= 9; i++) {pool.execute(()->{System.out.println(Thread.currentThread().getName()+"--->"+"ok");});}} }

(4):關(guān)于拒絕策略

  • new ThreadPoolExecutor.AbortPolicy() 這個(gè)是默認(rèn)的拒絕策略 是拋出異常的
  • new ThreadPoolExecutor.CallerRunsPolicy() 這個(gè)是讓調(diào)用者去執(zhí)行這個(gè)任務(wù)
  • new ThreadPoolExecutor.DiscardPolicy() 這個(gè)是直接丟掉任務(wù) 不拋異常
  • new ThreadPoolExecutor.DiscardOldestPolicy() 丟掉最早執(zhí)行的任務(wù) 然后再執(zhí)行本任務(wù)

6:關(guān)閉線程池

總結(jié)

以上是生活随笔為你收集整理的java并发之线程池的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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