自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

被開發(fā)者拋棄的 Executors,錯(cuò)在哪兒?

開發(fā) 后端
日常開發(fā)中,應(yīng)該收緊對線程池的創(chuàng)建,由開發(fā)人員明確線程池的運(yùn)行規(guī)則,以此來盡量規(guī)避其資源耗盡的風(fēng)險(xiǎn)。線程池是個(gè)好東西,但是怎么創(chuàng)建是一個(gè)問題。

一、序

在 Java 領(lǐng)域內(nèi),我們使用多線程的方式來實(shí)現(xiàn)并發(fā)編程。而線程本身是操作系統(tǒng)的一個(gè)概念,雖然不同的語言對線程都進(jìn)行了一些封裝,但是最終都是調(diào)用到操作系統(tǒng)中去創(chuàng)建和調(diào)度線程。

既然線程是一項(xiàng)重要的系統(tǒng)資源,為了更合理的利用此資源,我們會(huì)使用池化技術(shù)來優(yōu)化線程的創(chuàng)建和銷毀,這就是線程池。

[[314821]]

在我們學(xué)習(xí)并發(fā)編程的時(shí)候,線程可以利用 Thread 來創(chuàng)建并通過 start() 來啟動(dòng)一個(gè)線,但在成熟的項(xiàng)目中,基本上是不允許這樣操作線程的,都需要通過線程池去收斂線程的使用,所以線程池是必須的。

Java 的線程池可以通過 ThreadPoolExecutor 來構(gòu)造,在其中提供非常完備的構(gòu)造方法,可以根據(jù)我們的業(yè)務(wù)需求靈活的構(gòu)造線程池。同時(shí) Java 還提供了一個(gè) Executors,它內(nèi)部提供了很多包裝的方法,利用它可以幫我們快速的構(gòu)建線程池。

原本 Executors 的目的就是為了讓我們更方便的使用線程池,但是《阿里巴巴Java開發(fā)手冊》也明確指出,直接使用 Executors 的缺陷。

手冊中提到強(qiáng)制不允許使用 Executors 去創(chuàng)建線程池,而是應(yīng)該使用退化到最原始的 ThreadPoolExecutor 的方式。

被開發(fā)者拋棄的 Executors,錯(cuò)在哪兒?

日常開發(fā)中,應(yīng)該收緊對線程池的創(chuàng)建,由開發(fā)人員明確線程池的運(yùn)行規(guī)則,以此來盡量規(guī)避其資源耗盡的風(fēng)險(xiǎn)。

線程池是個(gè)好東西,但是怎么創(chuàng)建是一個(gè)問題。

二、Executors 怎么了?

1. 不被允許的 Executors

不應(yīng)該使用 Executors 的原因,其實(shí)《阿里巴巴Java開發(fā)手冊》里已經(jīng)寫明了,當(dāng)需要處理大量任務(wù)的時(shí)候,可能會(huì)出現(xiàn) OOM 異常,但它們出現(xiàn) OOM 的原因并不一樣。

ThreadPoolExecutor 的構(gòu)造方法中,提供了很多參數(shù)的配置,其中與 Executors 出現(xiàn) OOM 相關(guān)的就有 2 個(gè):核心線程數(shù)和等待隊(duì)列。

先來看看 FixedThreadPool 和 SingleThreadPool 出現(xiàn) OOM 的原因。

它們的問題在于等待隊(duì)列使用了 LinkedBlockingQueue 這個(gè)以鏈表實(shí)現(xiàn)的無界隊(duì)列(最大長度是 Integer.MAX_VALUE),最終導(dǎo)致堆積了大量等待處理的任務(wù),從而導(dǎo)致頻繁的 GC,最終觸發(fā) OOM。

  1. java.lang.OutOfMemoryError: GC overhead limit exceeded 

再來看看 CachedThreadPool 出現(xiàn) OOM 的原因。

它的問題在于核心線程數(shù)設(shè)置為了 Integer.MAX_VALUE,并且等待隊(duì)列是一個(gè) SynchronousQueue。

SynchronousQueue 是一個(gè)沒有數(shù)據(jù)緩沖的阻塞隊(duì)列,它極易被阻塞。在等待隊(duì)列被阻塞的時(shí)候,如果線程數(shù)量還沒有達(dá)到核心線程數(shù)限制的數(shù)量時(shí),線程池的策略是創(chuàng)建新的線程來處理新的任務(wù)。

也就是說,是核心線程數(shù)和等待隊(duì)列 SynchronousQueue 合力造成了線程會(huì)跟隨任務(wù)不斷的被創(chuàng)建,直到觸發(fā) OOM。

  1. java.lang.OutOfMemoryError: pthread_creat (1040KB stack) failed: Try again 

ScheduledThreadPool 的等待隊(duì)列使用的是 DelayedWorkQueue,原理也是類似的,最終會(huì)導(dǎo)致創(chuàng)建大量的線程而拋出 OOM。

線程是一種系統(tǒng)資源,本身創(chuàng)建就會(huì)帶來內(nèi)存開銷,同時(shí)操作系統(tǒng)對單進(jìn)程可創(chuàng)建的線程數(shù)也是有限制的。

在 Android 中,每個(gè)線程初始化都需要 mmap 一定的堆內(nèi)存,在默認(rèn)的情況下,初始化一個(gè)線程大約需要 mmap 1MB 左右的內(nèi)存空間。同時(shí)系統(tǒng)本身也會(huì)對每個(gè)進(jìn)程可創(chuàng)建的線程數(shù),做一定的限制,這個(gè)限制在 /proc/pid/limits 中,不同的廠商對這個(gè)限制也有所不同,當(dāng)超出限制時(shí),哪怕堆上還有可用內(nèi)存,依然會(huì)拋出 OOM。

2. Executors 錯(cuò)在哪兒了?

Executors 會(huì)在任務(wù)過多的時(shí)候,導(dǎo)致資源耗盡而觸發(fā) OOM,這是它帶來的危害。

Executors 最大的問題,在于沒有邊界。

在系統(tǒng)環(huán)境良好,任務(wù)不多的時(shí)候 Executors 創(chuàng)建的線程池,都是可以正常工作的。

但是一旦有重壓,我們就無法預(yù)知什么時(shí)候會(huì)出現(xiàn)問題,這就是沒有邊界,沒有邊界就意味著不可控。

我們很難去信任一段不可控的代碼,它什么時(shí)候出現(xiàn)問題,完全是不可預(yù)知的,這才是 Executors 最大的問題。

除此之外,Executors 封裝了太多線程池的細(xì)節(jié),本身也不建議使用。例如通常我們需要給線程池創(chuàng)建的線程,起一個(gè)有意義的名稱,方便在出現(xiàn)異常的時(shí)候排查問題;再例如對與線程池的拒絕策略,我們需要深思熟慮的定義,是直接拋棄還是持久化下來延遲處理。

去思考一個(gè)線程池的不同參數(shù)帶來的策略細(xì)節(jié),才是使用線程池的一個(gè)良好的開發(fā)習(xí)慣。

三. 小結(jié)時(shí)刻

本文我們聊了關(guān)于創(chuàng)建線程池,使用 Executors 創(chuàng)建的線程池會(huì)有 OOM 的風(fēng)險(xiǎn),應(yīng)該使用 ThreadPoolExecutor 去創(chuàng)建線程池。通過思考業(yè)務(wù)來明確配置線程池不同的參數(shù),例如線程池、等待隊(duì)列、拒絕策略等等。

責(zé)任編輯:趙寧寧 來源: 承香墨影
相關(guān)推薦

2020-02-11 17:15:09

開發(fā)者拋棄 Executors

2014-04-29 14:52:06

大數(shù)據(jù)

2011-12-12 13:09:45

云計(jì)算

2015-08-27 13:45:25

2023-09-12 11:38:18

2019-07-23 16:00:36

區(qū)塊鏈存儲(chǔ)5G

2022-02-25 10:03:11

對象數(shù)據(jù)算法

2015-10-23 11:40:08

SaaS應(yīng)用開發(fā)

2013-12-04 09:33:15

軟件成本

2014-04-17 10:16:50

2013-05-10 10:58:56

ERP

2017-06-22 10:39:06

Android開發(fā)者未來

2017-10-11 11:17:16

SaaS出路中國式

2020-04-21 16:01:13

自動(dòng)駕駛新基建工信部

2020-03-25 09:20:21

自然語言處理

2012-10-25 16:40:11

WOT高效數(shù)據(jù)中心數(shù)據(jù)中心

2024-11-21 17:35:10

2015-01-08 14:52:29

google云計(jì)算分布式計(jì)算框架

2015-10-13 15:58:38

Javascript循環(huán)變量

2017-09-05 08:30:13

機(jī)箱智商產(chǎn)品
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)