最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

你都理解創(chuàng)建線程池的參數(shù)嗎?

 更新時間:2019年04月20日 15:55:06   作者:Java科代表  
這篇文章主要介紹了創(chuàng)建線程池參數(shù),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

多線程可以說是面試官最喜歡拿來問的題目之一了,可謂是老生之常談,不管你是新手還是老司機,我相信你一定會在面試過程中遇到過有關多線程的一些問題。那我現(xiàn)在就充當一次面試官,我來問你:

現(xiàn)有一個線程池,參數(shù)corePoolSize = 5,maximumPoolSize = 10,BlockingQueue阻塞隊列長度為5,此時有4個任務同時進來,問:線程池會創(chuàng)建幾條線程?

如果4個任務還沒處理完,這時又同時進來2個任務,問:線程池又會創(chuàng)建幾條線程還是不會創(chuàng)建?

如果前面6個任務還是沒有處理完,這時又同時進來5個任務,問:線程池又會創(chuàng)建幾條線程還是不會創(chuàng)建?

如果你此時一臉懵逼,請不要慌,問題不大。

創(chuàng)建線程池的構造方法的參數(shù)都有哪些?

要回答這個問題,我們需要從創(chuàng)建線程池的參數(shù)去找答案:

java.util.concurrent.ThreadPoolExecutor#ThreadPoolExecutor:

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.acc = System.getSecurityManager() == null ? null : AccessController.getContext();
  this.corePoolSize = corePoolSize;
  this.maximumPoolSize = maximumPoolSize;
  this.workQueue = workQueue;
  this.keepAliveTime = unit.toNanos(keepAliveTime);
  this.threadFactory = threadFactory;
  this.handler = handler;
}

創(chuàng)建線程池一共有7個參數(shù),從源碼可知,corePoolSize和maximumPoolSize都不能小于0,且核心線程數(shù)不能大于最大線程數(shù)。

下面我來解釋一下這7個參數(shù)的用途:

corePoolSize

線程池核心線程數(shù)量,核心線程不會被回收,即使沒有任務執(zhí)行,也會保持空閑狀態(tài)。

maximumPoolSize

池允許最大的線程數(shù),當線程數(shù)量達到corePoolSize,且workQueue隊列塞滿任務了之后,繼續(xù)創(chuàng)建線程。

keepAliveTime

超過corePoolSize之后的“臨時線程”的存活時間。

unit

keepAliveTime的單位。

workQueue

當前線程數(shù)超過corePoolSize時,新的任務會處在等待狀態(tài),并存在workQueue中,BlockingQueue是一個先進先出的阻塞式隊列實現(xiàn),底層實現(xiàn)會涉及Java并發(fā)的AQS機制,有關于AQS的相關知識,我會單獨寫一篇,敬請期待。

threadFactory

創(chuàng)建線程的工廠類,通常我們會自頂一個threadFactory設置線程的名稱,這樣我們就可以知道線程是由哪個工廠類創(chuàng)建的,可以快速定位。

handler

線程池執(zhí)行拒絕策略,當線數(shù)量達到maximumPoolSize大小,并且workQueue也已經塞滿了任務的情況下,線程池會調用handler拒絕策略來處理請求。

系統(tǒng)默認的拒絕策略有以下幾種:

  1. AbortPolicy:為線程池默認的拒絕策略,該策略直接拋異常處理。
  2. DiscardPolicy:直接拋棄不處理。
  3. DiscardOldestPolicy:丟棄隊列中最老的任務。
  4. CallerRunsPolicy:將任務分配給當前執(zhí)行execute方法線程來處理。

我們還可以自定義拒絕策略,只需要實現(xiàn)RejectedExecutionHandler接口即可,友好的拒絕策略實現(xiàn)有如下:

  1. 將數(shù)據(jù)保存到數(shù)據(jù),待系統(tǒng)空閑時再進行處理
  2. 將數(shù)據(jù)用日志進行記錄,后由人工處理

現(xiàn)在我們回到剛開始的問題就很好回答了:
線程池corePoolSize=5,線程初始化時不會自動創(chuàng)建線程,所以當有4個任務同時進來時,執(zhí)行execute方法會新建【4】條線程來執(zhí)行任務;

前面的4個任務都沒完成,現(xiàn)在又進來2個隊列,會新建【1】條線程來執(zhí)行任務,這時poolSize=corePoolSize,還剩下1個任務,線程池會將剩下這個任務塞進阻塞隊列中,等待空閑線程執(zhí)行;

如果前面6個任務還是沒有處理完,這時又同時進來了5個任務,此時還沒有空閑線程來執(zhí)行新來的任務,所以線程池繼續(xù)將這5個任務塞進阻塞隊列,但發(fā)現(xiàn)阻塞隊列已經滿了,核心線程也用完了,還剩下1個任務不知道如何是好,于是線程池只能創(chuàng)建【1】條“臨時”線程來執(zhí)行這個任務了;

這里創(chuàng)建的線程用“臨時”來描述還是因為它們不會長期存在于線程池,它們的存活時間為keepAliveTime,此后線程池會維持最少corePoolSize數(shù)量的線程。

為什么不建議使用Executors創(chuàng)建線程池?

JDK為我們提供了Executors線程池工具類,里面有默認的線程池創(chuàng)建策略,大概有以下幾種:

  1. FixedThreadPool:線程池線程數(shù)量固定,即corePoolSize和maximumPoolSize數(shù)量一樣。
  2. SingleThreadPool:單個線程的線程池。
  3. CachedThreadPool:初始核心線程數(shù)量為0,最大線程數(shù)量為Integer.MAX_VALUE,線程空閑時存活時間為60秒,并且它的阻塞隊列為SynchronousQueue,它的初始長度為0,這會導致任務每次進來都會創(chuàng)建線程來執(zhí)行,在線程空閑時,存活時間到了又會釋放線程資源。
  4. ScheduledThreadPool:創(chuàng)建一個定長的線程池,而且支持定時的以及周期性的任務執(zhí)行,類似于Timer。

用Executors工具類雖然很方便,我依然不推薦大家使用以上默認的線程池創(chuàng)建策略,阿里巴巴開發(fā)手冊也是強制不允許使用Executors來創(chuàng)建線程池,我們從JDK源碼中尋找一波答案:
java.util.concurrent.Executors:

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

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

// CachedThreadPool
public static ExecutorService newCachedThreadPool() {
  // 允許創(chuàng)建線程數(shù)為Integer.MAX_VALUE
  return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                 60L, TimeUnit.SECONDS,
                 new SynchronousQueue<Runnable>());
}

// ScheduledThreadPool
public ScheduledThreadPoolExecutor(int corePoolSize) {
  // 允許創(chuàng)建線程數(shù)為Integer.MAX_VALUE
    super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
       new DelayedWorkQueue());
  }

public LinkedBlockingQueue() {
  // 允許隊列長度最大為Integer.MAX_VALUE
  this(Integer.MAX_VALUE);
}

從JDK源碼可看出,Executors工具類無非是把一些特定參數(shù)進行了封裝,并提供一些方法供我們調用而已,我們并不能靈活地填寫參數(shù),策略過于簡單,不夠友好。

CachedThreadPool和ScheduledThreadPool最大線程數(shù)為Integer.MAX_VALUE,如果線程無限地創(chuàng)建,會造成OOM異常。

LinkedBlockingQueue基于鏈表的FIFO隊列,是無界的,默認大小是Integer.MAX_VALUE,因此FixedThreadPool和SingleThreadPool的阻塞隊列長度為Integer.MAX_VALUE,如果此時隊列被無限地堆積任務,會造成OOM異常。

以上所述是小編給大家介紹的創(chuàng)建線程池參數(shù)詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

  • SpringBoot記錄Http請求日志的方法

    SpringBoot記錄Http請求日志的方法

    這篇文章主要介紹了SpringBoot記錄Http請求日志的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • Spring @Scheduled的坑及解決

    Spring @Scheduled的坑及解決

    這篇文章主要介紹了Spring @Scheduled的坑及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • SpringAOP 構造注入的實現(xiàn)步驟

    SpringAOP 構造注入的實現(xiàn)步驟

    這篇文章主要介紹了SpringAOP_構造注入的實現(xiàn)步驟,幫助大家更好的理解和學習使用spring框架,感興趣的朋友可以了解下
    2021-05-05
  • 短網(wǎng)址的原理與生成方法(Java實現(xiàn))

    短網(wǎng)址的原理與生成方法(Java實現(xiàn))

    這篇文章主要給大家介紹了關于短網(wǎng)址的原理與生成方法,利用的是Java實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • 深入了解Java接口回調機制

    深入了解Java接口回調機制

    這篇文章主要介紹了Java接口回調機制,下面我們來一起學習一下吧
    2019-05-05
  • SpringBoot、mybatis返回樹結構的數(shù)據(jù)實現(xiàn)

    SpringBoot、mybatis返回樹結構的數(shù)據(jù)實現(xiàn)

    本文主要介紹了SpringBoot、mybatis返回樹結構的數(shù)據(jù)實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • IDEA中如何移除未使用的包

    IDEA中如何移除未使用的包

    這篇文章主要介紹了IDEA中如何移除未使用的包問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • Java編程實現(xiàn)beta分布的采樣或抽樣實例代碼

    Java編程實現(xiàn)beta分布的采樣或抽樣實例代碼

    這篇文章主要介紹了Java編程實現(xiàn)beta分布的采樣或抽樣實例,分享了相關代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-01-01
  • java代碼審計之目錄遍歷的解決

    java代碼審計之目錄遍歷的解決

    目錄穿越漏洞,也叫做目錄遍歷/路徑遍歷漏洞,本文主要介紹了java代碼審計之目錄遍歷的解決,文中通過案例介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-06-06
  • SpringBoot整合mybatis-generator-maven-plugin的方法

    SpringBoot整合mybatis-generator-maven-plugin的方法

    這篇文章主要介紹了SpringBoot整合mybatis-generator-maven-plugin,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11

最新評論

黄梅县| 盐池县| 泉州市| 宜兰市| 玉山县| 土默特右旗| 图木舒克市| 靖宇县| 泗洪县| 桐庐县| 尚义县| 江源县| 清远市| 永泰县| 田林县| 古交市| 桐梓县| 吉水县| 沙雅县| 东方市| 红河县| 兴和县| 宁阳县| 准格尔旗| 化德县| 都昌县| 丹阳市| 永善县| 桑植县| 石柱| 临颍县| 浮梁县| 临桂县| 壶关县| 绥棱县| 新乡县| 太白县| 溧水县| 鹰潭市| 江西省| 昌平区|