电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

Java 線程池的作用以及該如何使用

瀏覽:53日期:2022-08-17 15:56:26

服務(wù)端應(yīng)用程序(如數(shù)據(jù)庫(kù)和 Web 服務(wù)器)需要處理來(lái)自客戶端的高并發(fā)、耗時(shí)較短的請(qǐng)求任務(wù),所以頻繁的創(chuàng)建處理這些請(qǐng)求的所需要的線程就是一個(gè)非常消耗資源的操作。常規(guī)的方法是針對(duì)一個(gè)新的請(qǐng)求創(chuàng)建一個(gè)新線程,雖然這種方法似乎易于實(shí)現(xiàn),但它有重大缺點(diǎn)。為每個(gè)請(qǐng)求創(chuàng)建新線程將花費(fèi)更多的時(shí)間,在創(chuàng)建和銷(xiāo)毀線程時(shí)花費(fèi)更多的系統(tǒng)資源。因此同時(shí)創(chuàng)建太多線程的 JVM 可能會(huì)導(dǎo)致系統(tǒng)內(nèi)存不足,這就需要限制要?jiǎng)?chuàng)建的線程數(shù),也就是需要使用到線程池。

一、什么是 Java 中的線程池?

線程池技術(shù)就是線程的重用技術(shù),使用之前創(chuàng)建好的線程來(lái)執(zhí)行當(dāng)前任務(wù),并提供了針對(duì)線程周期開(kāi)銷(xiāo)和資源沖突問(wèn)題的解決方案。 由于請(qǐng)求到達(dá)時(shí)線程已經(jīng)存在,因此消除了線程創(chuàng)建過(guò)程導(dǎo)致的延遲,使應(yīng)用程序得到更快的響應(yīng)。

Java提供了以Executor接口及其子接口ExecutorService和ThreadPoolExecutor為中心的執(zhí)行器框架。通過(guò)使用Executor,完成線程任務(wù)只需實(shí)現(xiàn) Runnable接口并將其交給執(zhí)行器執(zhí)行即可。 為您封裝好線程池,將您的編程任務(wù)側(cè)重于具體任務(wù)的實(shí)現(xiàn),而不是線程的實(shí)現(xiàn)機(jī)制。 若要使用線程池,我們首先創(chuàng)建一個(gè) ExecutorService對(duì)象,然后向其傳遞一組任務(wù)。ThreadPoolExcutor 類(lèi)則可以設(shè)置線程池初始化和最大的線程容量。

Java 線程池的作用以及該如何使用

上圖表示線程池初始化具有3 個(gè)線程,任務(wù)隊(duì)列中有5 個(gè)待運(yùn)行的任務(wù)對(duì)象。

執(zhí)行器線程池方法

方法 描述 newFixedThreadPool(int) 創(chuàng)建具有固定的線程數(shù)的線程池,int參數(shù)表示線程池內(nèi)線程的數(shù)量 newCachedThreadPool() 創(chuàng)建一個(gè)可緩存線程池,該線程池可靈活回收空閑線程。若無(wú)空閑線程,則新建線程處理任務(wù)。 newSingleThreadExecutor() 創(chuàng)建一個(gè)單線程化的線程池,它只會(huì)用唯一的工作線程來(lái)執(zhí)行任務(wù) newScheduledThreadPool 創(chuàng)建一個(gè)定長(zhǎng)線程池,支持定時(shí)及周期性任務(wù)執(zhí)行

在固定線程池的情況下,如果執(zhí)行器當(dāng)前運(yùn)行的所有線程,則掛起的任務(wù)將放在隊(duì)列中,并在線程變?yōu)榭臻e時(shí)執(zhí)行。

二、線程池示例

在下面的內(nèi)容中,我們將介紹線程池的executor執(zhí)行器。

創(chuàng)建線程池處理任務(wù)要遵循的步驟 創(chuàng)建一個(gè)任務(wù)對(duì)象(實(shí)現(xiàn)Runnable接口),用于執(zhí)行具體的任務(wù)邏輯 使用Executors創(chuàng)建線程池ExecutorService 將待執(zhí)行的任務(wù)對(duì)象交給ExecutorService進(jìn)行任務(wù)處理 停掉 Executor 線程池

//第一步: 創(chuàng)建一個(gè)任務(wù)對(duì)象(實(shí)現(xiàn)Runnable接口),用于執(zhí)行具體的任務(wù)邏輯 (Step 1) class Task implements Runnable { private String name; public Task(String s) { name = s; } // 打印任務(wù)名稱(chēng)并Sleep 1秒 // 整個(gè)處理流程執(zhí)行5次 public void run() { try{ for (int i = 0; i<=5; i++) {if (i==0) { Date d = new Date(); SimpleDateFormat ft = new SimpleDateFormat('hh:mm:ss'); System.out.println('任務(wù)初始化' + name +' = ' + ft.format(d)); //第一次執(zhí)行的時(shí)候,打印每一個(gè)任務(wù)的名稱(chēng)及初始化的時(shí)間}else{ Date d = new Date(); SimpleDateFormat ft = new SimpleDateFormat('hh:mm:ss'); System.out.println('任務(wù)正在執(zhí)行' + name +' = ' + ft.format(d)); // 打印每一個(gè)任務(wù)處理的執(zhí)行時(shí)間}Thread.sleep(1000); } System.out.println('任務(wù)執(zhí)行完成' + name); } catch(InterruptedException e) { e.printStackTrace(); } }}

測(cè)試用例

public class ThreadPoolTest { // 線程池里面最大線程數(shù)量 static final int MAX_SIZE = 3; public static void main (String[] args) { // 創(chuàng)建5個(gè)任務(wù) Runnable r1 = new Task('task 1'); Runnable r2 = new Task('task 2'); Runnable r3 = new Task('task 3'); Runnable r4 = new Task('task 4'); Runnable r5 = new Task('task 5'); // 第二步:創(chuàng)建一個(gè)固定線程數(shù)量的線程池,線程數(shù)為MAX_SIZE ExecutorService pool = Executors.newFixedThreadPool(MAX_SIZE); // 第三步:將待執(zhí)行的任務(wù)對(duì)象交給ExecutorService進(jìn)行任務(wù)處理 pool.execute(r1); pool.execute(r2); pool.execute(r3); pool.execute(r4); pool.execute(r5); // 第四步:關(guān)閉線程池 pool.shutdown(); }} 示例執(zhí)行結(jié)果

任務(wù)初始化task 1 = 05:25:55任務(wù)初始化task 2 = 05:25:55任務(wù)初始化task 3 = 05:25:55任務(wù)正在執(zhí)行task 3 = 05:25:56任務(wù)正在執(zhí)行task 1 = 05:25:56任務(wù)正在執(zhí)行task 2 = 05:25:56任務(wù)正在執(zhí)行task 1 = 05:25:57任務(wù)正在執(zhí)行task 3 = 05:25:57任務(wù)正在執(zhí)行task 2 = 05:25:57任務(wù)正在執(zhí)行task 3 = 05:25:58任務(wù)正在執(zhí)行task 1 = 05:25:58任務(wù)正在執(zhí)行task 2 = 05:25:58任務(wù)正在執(zhí)行task 2 = 05:25:59任務(wù)正在執(zhí)行task 3 = 05:25:59任務(wù)正在執(zhí)行task 1 = 05:25:59任務(wù)正在執(zhí)行task 1 = 05:26:00任務(wù)正在執(zhí)行task 2 = 05:26:00任務(wù)正在執(zhí)行task 3 = 05:26:00任務(wù)執(zhí)行完成task 3任務(wù)執(zhí)行完成task 2任務(wù)執(zhí)行完成task 1任務(wù)初始化task 5 = 05:26:01任務(wù)初始化task 4 = 05:26:01任務(wù)正在執(zhí)行task 4 = 05:26:02任務(wù)正在執(zhí)行task 5 = 05:26:02任務(wù)正在執(zhí)行task 4 = 05:26:03任務(wù)正在執(zhí)行task 5 = 05:26:03任務(wù)正在執(zhí)行task 5 = 05:26:04任務(wù)正在執(zhí)行task 4 = 05:26:04任務(wù)正在執(zhí)行task 4 = 05:26:05任務(wù)正在執(zhí)行task 5 = 05:26:05任務(wù)正在執(zhí)行task 4 = 05:26:06任務(wù)正在執(zhí)行task 5 = 05:26:06任務(wù)執(zhí)行完成task 4任務(wù)執(zhí)行完成task 5

如程序執(zhí)行結(jié)果中顯示的一樣,任務(wù) 4 或任務(wù) 5 僅在池中的線程變?yōu)榭臻e時(shí)才執(zhí)行。在此之前,額外的任務(wù)將放在待執(zhí)行的隊(duì)列中。

Java 線程池的作用以及該如何使用

線程池執(zhí)行前三個(gè)任務(wù),線程池內(nèi)線程回收空出來(lái)之后再去處理執(zhí)行任務(wù) 4 和 5

Java 線程池的作用以及該如何使用

使用這種線程池方法的一個(gè)主要優(yōu)點(diǎn)是,假如您希望一次處理10000個(gè)請(qǐng)求,但不希望創(chuàng)建10000個(gè)線程,從而避免造成系統(tǒng)資源的過(guò)量使用導(dǎo)致的宕機(jī)。您可以使用此方法創(chuàng)建一個(gè)包含500個(gè)線程的線程池,并且可以向該線程池提交500個(gè)請(qǐng)求。ThreadPool此時(shí)將創(chuàng)建最多500個(gè)線程,一次處理500個(gè)請(qǐng)求。在任何一個(gè)線程的進(jìn)程完成之后,ThreadPool將在內(nèi)部將第501個(gè)請(qǐng)求分配給該線程,并將繼續(xù)對(duì)所有剩余的請(qǐng)求執(zhí)行相同的操作。在系統(tǒng)資源比較緊張的情況下,線程池是保證程序穩(wěn)定運(yùn)行的一個(gè)有效的解決方案。

三、使用線程池的注意事項(xiàng)與調(diào)優(yōu) 死鎖: 雖然死鎖可能發(fā)生在任何多線程程序中,但線程池引入了另一個(gè)死鎖案例,其中所有執(zhí)行線程都在等待隊(duì)列中某個(gè)阻塞線程的執(zhí)行結(jié)果,導(dǎo)致線程無(wú)法繼續(xù)執(zhí)行。 線程泄漏 : 如果線程池中線程在任務(wù)完成時(shí)未正確返回,將發(fā)生線程泄漏問(wèn)題。例如,某個(gè)線程引發(fā)異常并且池類(lèi)沒(méi)有捕獲此異常,則線程將異常退出,從而線程池的大小將減小一個(gè)。如果這種情況重復(fù)多次,則線程池最終將變?yōu)榭眨瑳](méi)有線程可用于執(zhí)行其他任務(wù)。 線程頻繁輪換: 如果線程池大小非常大,則線程之間進(jìn)行上下文切換會(huì)浪費(fèi)很多時(shí)間。所以在系統(tǒng)資源允許的情況下,也不是線程池越大越好。

線程池大小優(yōu)化: 線程池的最佳大小取決于可用的處理器數(shù)量和待處理任務(wù)的性質(zhì)。對(duì)于CPU密集型任務(wù),假設(shè)系統(tǒng)有N個(gè)邏輯處理核心,N 或 N+1 的最大線程池?cái)?shù)量大小將實(shí)現(xiàn)最大效率。對(duì)于 I/O密集型任務(wù),需要考慮請(qǐng)求的等待時(shí)間(W)和服務(wù)處理時(shí)間(S)的比例,線程池最大大小為 N*(1+ W/S)會(huì)實(shí)現(xiàn)最高效率。

不要教條的使用上面的總結(jié),需要根據(jù)自己的應(yīng)用任務(wù)處理類(lèi)型進(jìn)行靈活的設(shè)置與調(diào)優(yōu),其中少不了測(cè)試實(shí)驗(yàn)。

原文鏈接:字母哥博客。

以上就是Java 線程池的作用以及該如何使用的詳細(xì)內(nèi)容,更多關(guān)于Java 線程池的作用和使用的資料請(qǐng)關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 定制奶茶纸杯_定制豆浆杯_广东纸杯厂_[绿保佳]一家专业生产纸杯碗的厂家 | 纯水电导率测定仪-万用气体检测仪-低钠测定仪-米沃奇科技(北京)有限公司www.milwaukeeinst.cn 锂辉石检测仪器,水泥成分快速分析仪-湘潭宇科分析仪器有限公司 手术室净化装修-手术室净化工程公司-华锐手术室净化厂家 | 密集柜_档案密集柜_智能密集架_密集柜厂家_密集架价格-智英伟业 密集架-密集柜厂家-智能档案密集架-自动选层柜订做-河北风顺金属制品有限公司 | 临海涌泉蜜桔官网|涌泉蜜桔微商批发代理|涌泉蜜桔供应链|涌泉蜜桔一件代发 | 车间除尘设备,VOCs废气处理,工业涂装流水线,伸缩式喷漆房,自动喷砂房,沸石转轮浓缩吸附,机器人喷粉线-山东创杰智慧 | ?水马注水围挡_塑料注水围挡_防撞桶-常州瑞轩水马注水围挡有限公司 | 扬尘监测_扬尘监测系统_带证扬尘监测设备 - 郑州港迪科技有限公司 | China plate rolling machine manufacturer,cone rolling machine-Saint Fighter | 安规电容|薄膜电容|陶瓷电容|智旭JEC安规电容厂家 | 酵素生产厂家_酵素OEM_酵素加盟_酵素ODM_酵素原料厂家_厦门益力康 | 生物颗粒燃烧机-生物质燃烧机-热风炉-生物颗粒蒸汽发生器-丽水市久凯能源设备有限公司 | 并网柜,汇流箱,电控设备,中高低压开关柜,电气电力成套设备,PLC控制设备订制厂家,江苏昌伟业新能源科技有限公司 | 游戏版号转让_游戏资质出售_游戏公司转让-【八九买卖网】 | 多功能干燥机,过滤洗涤干燥三合一设备-无锡市张华医药设备有限公司 | 筛分机|振动筛分机|气流筛分机|筛分机厂家-新乡市大汉振动机械有限公司 | 电动卫生级调节阀,电动防爆球阀,电动软密封蝶阀,气动高压球阀,气动对夹蝶阀,气动V型调节球阀-上海川沪阀门有限公司 | ASA膜,ASA共挤料,篷布色母料-青岛未来化学有限公司 | 三效蒸发器_多效蒸发器价格_四效三效蒸发器厂家-青岛康景辉 | 耐酸泵,耐腐蚀真空泵,耐酸真空泵-淄博华舜耐腐蚀真空泵有限公司 精密模具-双色注塑模具加工-深圳铭洋宇通 | 蜗轮丝杆升降机-螺旋升降机-丝杠升降机厂家-润驰传动 | 北京开业庆典策划-年会活动策划公司-舞龙舞狮团大鼓表演-北京盛乾龙狮鼓乐礼仪庆典策划公司 | 培训中心-翰香原香酥板栗饼加盟店总部-正宗板栗酥饼技术 | 宁波普瑞思邻苯二甲酸盐检测仪,ROHS2.0检测设备,ROHS2.0测试仪厂家 | pos机办理,智能/扫码/二维码/微信支付宝pos机-北京万汇通宝商贸有限公司 | 合金耐磨锤头_破碎机锤头_郑州市德勤建材有限公司 | 消防设施操作员考试报名时间,报名入口,报考条件 | 呼末二氧化碳|ETCO2模块采样管_气体干燥管_气体过滤器-湖南纳雄医疗器械有限公司 | 办公室家具公司_办公家具品牌厂家_森拉堡办公家具【官网】 | 复合土工膜厂家|hdpe防渗土工膜|复合防渗土工布|玻璃纤维|双向塑料土工格栅-安徽路建新材料有限公司 | 采暖炉_取暖炉_生物质颗粒锅炉_颗粒壁炉_厂家加盟批发_烟台蓝澳采暖设备有限公司 | 低温等离子清洗机(双气路进口)-嘉润万丰 | 中空玻璃生产线,玻璃加工设备,全自动封胶线,铝条折弯机,双组份打胶机,丁基胶/卧式/立式全自动涂布机,玻璃设备-山东昌盛数控设备有限公司 | 东莞爱加真空科技有限公司-进口真空镀膜机|真空镀膜设备|Polycold维修厂家 | 大型果蔬切片机-水果冬瓜削皮机-洗菜机切菜机-肇庆市凤翔餐饮设备有限公司 | 水冷式工业冷水机组_风冷式工业冷水机_水冷螺杆冷冻机组-深圳市普威机械设备有限公司 | 集装箱标准养护室-集装箱移动式养护室-广州璟业试验仪器有限公司 | 高通量组织研磨仪-多样品组织研磨仪-全自动组织研磨仪-研磨者科技(广州)有限公司 | 细胞染色-流式双标-试剂盒免费代做-上海研谨生物科技有限公司 | 光泽度计_测量显微镜_苏州压力仪_苏州扭力板手维修-苏州日升精密仪器有限公司 | 淘剧影院_海量最新电视剧,免费高清电影随心观看 | 药品冷藏箱厂家_低温冰箱_洁净工作台-济南欧莱博电子商务有限公司官网 |