




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第Java創(chuàng)建線程池為什么一定要用ThreadPoolExecutor目錄先說結(jié)論OOM風(fēng)險演示內(nèi)存溢出原因分析使用ThreadPoolExecutor來改進其他創(chuàng)建線程池的問題總結(jié)前言:
在Java語言中,并發(fā)編程都是依靠線程池完成的,而線程池的創(chuàng)建方式又有很多,但從大的分類來說,線程池的創(chuàng)建總共分為兩大類:手動方式使用ThreadPoolExecutor創(chuàng)建線程池和使用Executors執(zhí)行器自動創(chuàng)建線程池。那究竟要使用哪種方式來創(chuàng)建線程池呢?我們今天就來詳細的聊一聊。
先說結(jié)論
在Java語言中,一定要使用ThreadPoolExecutor手動的方式來創(chuàng)建線程池,因為這種方式可以通過參數(shù)來控制最大任務(wù)數(shù)和拒絕策略,讓線程池的執(zhí)行更加透明和可控,并且可以規(guī)避資源耗盡的風(fēng)險。
OOM風(fēng)險演示
假如我們使用了Executors執(zhí)行器自動創(chuàng)建線程池的方式來創(chuàng)建線程池,那么就會存現(xiàn)線程溢出的風(fēng)險,
以CachedThreadPool為例我們來演示一下:
importjava.util.ArrayList;
importjava.util.List;
importjava.util.concurrent.ExecutorService;
importjava.util.concurrent.Executors;
publicclassThreadPoolExecutorExample{
staticclassOOMClass{
//創(chuàng)建1MB大小的變量(1M=1024KB=1024*1024Byte)
privatebyte[]data_byte=newbyte[1*1024*1024];
publicstaticvoidmain(String[]args)throwsInterruptedException{
//使用執(zhí)行器自動創(chuàng)建線程池
ExecutorServicethreadPool=Executors.newCachedThreadPool();
ListObjectlist=newArrayList();
//添加任務(wù)
for(inti=0;ii++){
intfinalI=i;
threadPool.execute(newRunnable(){
@Override
publicvoidrun(){
//定時添加
try{
Thread.sleep(finalI*200);
}catch(InterruptedExceptione){
e.printStackTrace();
//將1M對象添加到集合
OOMClassoomClass=newOOMClass();
list.add(oomClass);
System.out.println("執(zhí)行任務(wù):"+finalI);
}
第2步將Idea中JVM最大運行內(nèi)存設(shè)置為10M(設(shè)置此值主要是為了方便演示),如下圖所示:
以上程序的執(zhí)行結(jié)果如下圖所示:
從上述結(jié)果可以看出,當線程執(zhí)行了7次之后就開始出現(xiàn)OutOfMemoryError內(nèi)存溢出的異常了。
內(nèi)存溢出原因分析
想要了解內(nèi)存溢出的原因,我們需要查看CachedThreadPool實現(xiàn)的細節(jié),它的源碼如下圖所示:
構(gòu)造函數(shù)的第2個參數(shù)被設(shè)置成了Integer.MAX_VALUE,這個參數(shù)的含義是最大線程數(shù),所以由于CachedThreadPool并不限制線程的數(shù)量,當任務(wù)數(shù)量特別多的時候,就會創(chuàng)建非常多的線程。而上面的OOM示例,每個線程至少要消耗1M大小的內(nèi)存,加上JDK系統(tǒng)類的加載也要占用一部分的內(nèi)存,所以當總的運行內(nèi)存大于10M的時候,就出現(xiàn)內(nèi)存溢出的問題了。
使用ThreadPoolExecutor來改進
接下來我們使用ThreadPoolExecutor來改進一下OOM的問題,我們使用ThreadPoolExecutor手動創(chuàng)建線程池的方式,創(chuàng)建一個最大線程數(shù)為2,最多可存儲2個任務(wù)的線程池,并且設(shè)置線程池的拒絕策略為忽略新任務(wù),這樣就能保證線程池的運行內(nèi)存大小不會超過10M了,
實現(xiàn)代碼如下:
importjava.util.ArrayList;
importjava.util.List;
importjava.util.concurrent.*;
*ThreadPoolExecutor演示示例
publicclassThreadPoolExecutorExample{
staticclassOOMClass{
//創(chuàng)建1MB大小的變量(1M=1024KB=1024*1024Byte)
privatebyte[]data_byte=newbyte[1*1024*1024];
publicstaticvoidmain(String[]args)throwsInterruptedException{
//手動創(chuàng)建線程池,最大線程數(shù)2,最多存儲2個任務(wù),其他任務(wù)會被忽略
ThreadPoolExecutorthreadPool=newThreadPoolExecutor(2,2,
0L,TimeUnit.SECONDS,newLinkedBlockingQueue(2),
newThreadPoolExecutor.DiscardPolicy());//拒絕策略:忽略任務(wù)
ListObjectlist=newArrayList();
//添加任務(wù)
for(inti=0;ii++){
intfinalI=i;
threadPool.execute(newRunnable(){
@Override
publicvoidrun(){
//定時添加
try{
Thread.sleep(finalI*200);
}catch(InterruptedExceptione){
e.printStackTrace();
//將1m對象添加到集合
OOMClassoomClass=newOOMClass();
list.add(oomClass);
System.out.println("執(zhí)行任務(wù):"+finalI);
//關(guān)閉線程池
threadPool.shutdown();
//檢測線程池的任務(wù)執(zhí)行完
while(!threadPool.awaitTermination(3,TimeUnit.SECONDS)){
System.out.println("線程池中還有任務(wù)在處理");
}
以上程序的執(zhí)行結(jié)果如下圖所示:
從上述結(jié)果可以看出,線程池從開始執(zhí)行到執(zhí)行結(jié)束都沒有出現(xiàn)OOM的異常,這就是手動創(chuàng)建線程池的優(yōu)勢。
其他創(chuàng)建線程池的問題
除了CachedThreadPool線程池之外,其他使用Executors自動創(chuàng)建線程池的方式,也存在著其他一些問題,
比如FixedThreadPool它的實現(xiàn)源碼如下:
而默認情況下任務(wù)隊列LinkedBlockingQueue的存儲容量是Integer.MAX_VALUE,也是趨向于無限大
如下圖所示:
這樣就也會造成,因為線程池的任務(wù)過多而導(dǎo)致的內(nèi)存溢出問題。其他幾個使用Executors自動創(chuàng)建線程池的方式也存在此問題,這里就不一一演示
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 智能玻璃自動門行業(yè)深度調(diào)研及發(fā)展戰(zhàn)略咨詢報告
- 買裝飾正規(guī)合同范例
- 智能攝影燈行業(yè)跨境出海戰(zhàn)略研究報告
- 燃料電池系統(tǒng)集成企業(yè)制定與實施新質(zhì)生產(chǎn)力戰(zhàn)略研究報告
- 代理解約合同范例
- 麗水拆除合同范例
- 與房屋買賣有關(guān)合同標準文本
- 光纜鋪設(shè)合同范例
- 鄉(xiāng)鎮(zhèn)衛(wèi)生院衛(wèi)生信息管理職責(zé)
- 線上教育平臺教師職責(zé)與分工
- HY/T 0379-2023赤潮災(zāi)害風(fēng)險評估與區(qū)劃導(dǎo)則
- 鄭和完整版本
- 2024年安慶市金融控股集團有限公司招聘筆試參考題庫附帶答案詳解
- 代收代付協(xié)議書模板(2篇)
- 汽車配件中英文名稱對照
- 大型峰會會務(wù)服務(wù)會務(wù)就餐保障方案
- 政務(wù)新聞攝影技巧培訓(xùn)課件
- 上海灘鋼琴簡譜數(shù)字雙手樂譜
- 2024年放射工作人員放射防護培訓(xùn)考試題及答案
- 《第七天》讀書分享交流會
- 師德師風(fēng)個人檔案表
評論
0/150
提交評論