成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用線程池也能搞崩系統,你見過嗎?

開發 架構
在面互聯網大廠的時候,一定會問并發,問并發的時候一定會問到線程池,問到線程池一定會問構造線程池的一些參數的含義

一、背景引入

今天跟大家聊一個互聯網大廠的Java面試題:使用無界隊列的線程池會導致內存飆升嗎?

因為在面互聯網大廠的時候,一定會問并發,問并發的時候一定會問到線程池,問到線程池一定會問構造線程池的一些參數的含義。

然后,有一些面試官會就線程池的具體場景,問一些可能會遇到的問題。

所以,在這里就可能有上述那樣一個面試中的問題,算是Java面試里相對來說高階一點的。

我相信大家一定起碼知道線程池是個什么東西的。簡單來說,就是維護一個池子,池子里面放了很多的線程。

然后來一個任務,某個線程就獲取這個任務來執行,任務執行完之后線程是不會釋放掉的,而是停留在線程池里繼續等待下一個任務。

這樣的一個好處是你沒必要自己手動頻繁的創建和銷毀線程,畢竟線程是較重的資源,頻繁的創建和銷毀對系統性能是沒好處的。

我們看看下面的圖,回顧一下線程池的含義。

二、線程池是如何構造的?

那么平時在Java里寫代碼的時候,大家記得不記得線程池是如何構造出來的呢?

是不是類似下面那樣的代碼,比如說我們構造一個線程數量固定的一個線程池:

那么Executors.newFixedThreadPool(10)內部到底又是如何構造出來線程池的呢?

其實很簡單,翻開JDK源碼就可以看到里面的代碼如下:

簡單來說,就是構造了一個ThreadPoolExecutor對象實例,你大致就認為他是一個線程池吧,傳入了一些參數,這些參數大致包含了:

  1. corePoolSize
  2. maximumPoolSize
  3. keepAliveTime
  4. workQueue

假如說我們構造線程池傳入的線程數量是10,那么在這里,corePoolSize和maximumSize都是10,keepAliveTime默認就是0,workQueue是一個無界的LinkedBlockingQueue。

接下來,我們具體來看看構造一個線程池傳入一些參數之后,具體這個線程池的運行原理是什么。

三、線程池的運行原理

簡單來說,剛開始的時候其實線程池里是空的,就是一個線程都沒有的,如下圖所示。

接著如果你使用線程池提交一個任務進去,希望由線程池里的一個線程來執行,如下代碼所示,就是提交一個任務:

這個時候,線程池會先看一下,現在池子里的線程數量有沒有有達到corePoolSize指定的數量。

現在線程池里的線程數量是0,然后corePoolSize是10,那么肯定沒達到了,所以直接會在線程池里創建一個線程出來然后執行這個任務,如下圖。

接著假如說,這個線程處理完一個任務了,那么此時線程是不會被銷毀的,他會一直等待下一個提交過來的任務。

那么,到底是怎么等待的呢?

很簡單,線程池會搭配一個workQueue,比如這里搭配的就是一個無界的LinkedBlockingQueue,幾乎可以無限量放入任務。

然后那個線程處理完一個任務之后,就會用阻塞的方式嘗試從任務隊列里獲取任務,如果隊列是空的,他就會阻塞卡在那兒不動,直到有人放一個任務到隊列里,他才會獲取到一個任務然后繼續執行,循環往復,如下圖。

接著再次提交任務,線程池一判斷發現,誒?好像線程數量才只有1個,完全比corePoolSize(10個)要小,那么繼續直接在池子里創建一個線程,然后處理這個任務,處理完了繼續嘗試從workQueue里阻塞式獲取任務。

一直重復上面的操作,直到線程池里有10個線程了,達到了corePoolSize指定的數量,如下圖。

這個時候你如果再提交任務,他一下子發現,誒?不對啊,線程池里已經有10個線程了,跟corePoolSize指定的線程數量一樣了。

那么現在,我就不需要創建任何一個額外的線程了,現在你只要提交任務,全部直接入隊到workQueue里就好。

此時線程池里的線程都阻塞式在workQueue上等待獲取任務,有一個任務進來就會喚醒一個線程來處理這個任務,處理完了任務再次阻塞在workQueue上嘗試獲取下一個任務,如下圖所示這個意思。

這里我們看到他用的是一個無界的LinkedBlockingQueue,但是假如說他用的是一個有界的隊列呢?

比如說限定好了隊列最多只能放10個任務,那么假如說,線程池里的線程來不及處理任務了,然后隊列一下子放滿了10個任務。

此時就會出現任務入隊的失敗,因為隊列滿了,無法入隊。

然后就會嘗試再次在線程池里創建線程,這個時候就會一直創建線程直到線程池里的線程數量達到maximumPoolSize指定的數量為止。

雖然這里fixed線程池默認corePoolSize和maximumPoolSize的數量都是一致的,但是可以假設此時maximumPoolSize的數量是20呢?

那么就會繼續創建線程,直到線程數量達到20個,然后用額外創建的10個線程在隊列滿的情況下,繼續處理任務。

整個過程,如下圖所示:

接著萬一隊列滿了,然后線程池的線程數量達到了maximumPoolSize指定的數量了,你額外創建線程都無法創建了,此時會如何呢?

答案是:會reject掉,不讓你繼續提交任務了,此時默認的就是拋出一個異常。

那么,在上圖中額外創建出來的,超出corePoolSize的那些線程呢?

他們一旦創建出來之后,會發現線程池數量已經超過corePoolSize了,此時他們會嘗試等待workQueue里的任務。

一旦超過keepAliveTime指定的時間,還獲取不到任務,比如keepAliveTime是60秒,那么假如超過60秒獲取不到任務,他就會自動釋放掉了,這個線程就銷毀了。

整個過程,如下圖所示。

四、無界隊列引發的內存飆升

明白了線程池的運行原理了,這個面試題就好解答了。

我們以最常用的fixed線程池舉例,他的線程池數量是固定的,因為他用的是近乎于無界的LinkedBlockingQueue,幾乎可以無限制的放入任務到隊列里。

所以只要線程池里的線程數量達到了corePoolSize指定的數量之后,接下來就維持這個固定數量的線程了。

然后,所有任務都會入隊到workQueue里去,線程從workQueue獲取任務來處理。

這個隊列幾乎永遠不會滿,當然這是幾乎,因為LinkedBlockingQueue默認的最大任務數量是Integer.MAX_VALUE,非常大,近乎于可以理解為無限吧。

只要隊列不滿,就跟maximumPoolSize、keepAliveTime這些沒關系了,因為不會創建超過corePoolSize數量的線程的。

同樣,給大家來一張圖,我們來看看:

那么此時萬一每個線程獲取到一個任務之后,他處理的時間特別特別的長,長到了令人發指的地步。比如處理一個任務要幾個小時,此時會如何?

當然會出現workQueue里不斷的積壓越來越多得任務,不停的增加。

這個過程中會導致機器的內存使用不停的飆升,最后也許極端情況下就導致JVM OOM了,系統就掛掉了。

所以這就是這個面試題背后你要知道的線程池的運行原理,以及可能遇到的一些問題,大家要做到心里有數。

責任編輯:姜華 來源: 今日頭條
相關推薦

2024-08-02 11:51:03

2023-06-08 07:48:03

Java線程池

2020-02-21 14:15:40

SimpleDateFJava多線程

2022-04-12 07:51:31

架構TPSQPS

2023-01-04 11:35:21

預測模型預售

2018-02-01 21:34:38

戴爾

2025-01-03 08:40:53

Java并發編程Guava庫

2022-10-25 17:53:09

Java線程池

2021-06-01 10:49:22

線程池Java開發

2021-06-03 14:23:57

線程線程池JAVA

2018-06-22 08:13:21

2023-09-08 08:42:01

數據場景項目

2021-09-01 07:21:40

ArrayPool源碼Bucket

2019-03-22 09:13:47

淘寶12306閑魚

2019-01-29 10:16:38

Redis高可用集群

2012-02-29 13:26:20

Java

2025-05-28 04:10:00

對象池性能業務場景

2021-09-22 15:18:48

HTTPS黑客數據安全

2012-05-05 09:47:55

喬布斯

2019-05-07 15:49:27

AI人工智能藝術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久伊人精品 | 免费在线日韩 | 欧美专区在线视频 | 精品日韩一区 | 黄色片在线看 | 精品久久一区 | 精品伊人久久 | 精品国产免费人成在线观看 | 日本中文字幕在线观看 | 黄色a三级 | 麻豆视频在线看 | 国产精品免费在线 | 91在线精品秘密一区二区 | 九九国产| 日本精品视频一区二区 | 精品日韩一区二区 | 日一区二区 | 亚洲顶级毛片 | 日韩精品视频中文字幕 | av在线播放国产 | 亚洲欧洲中文日韩 | 亚洲va欧美va天堂v国产综合 | 亚洲视频 欧美视频 | 日韩一二区 | 日韩精品一区二区三区中文字幕 | 91亚洲国产 | 91极品欧美视频 | 丝袜 亚洲 另类 欧美 综合 | 亚洲自拍偷拍欧美 | 天天艹| 午夜午夜精品一区二区三区文 | 欧美一区二区三区视频 | 日韩欧美国产一区二区 | 日本午夜免费福利视频 | 亚洲精品一区二区 | 国产成人精品午夜视频免费 | 国产一区二区三区色淫影院 | www.日韩系列 | 超碰免费观看 | 99久久久99久久国产片鸭王 | 在线欧美 |