第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定

Java線程池「異常處理」正確姿勢:有病就得治

標(biāo)簽:
Java

小姐姐味道【ID:xjjdog】
作者:十年架构,日百亿流量经验,与你分享。

5d2b43090001473b03650174.jpg

假设我们有一个线程池,由于程序需要,我们向该线程池中提交了好多好多任务,但是 这些任务都没有对异常进行try catch处理,并且运行的时候都抛出了异常 。这会对线程池的运行带来什么影响?

正确答案是:没有影响。这可不是好事情。


想一下,如果是你开发了一个线程池供开发者使用,你会不会对这种情况做处理?想想也是肯定的,不然你提供给别人使用的东西就是有问题的,欠考虑的。而且java线程池的主要开发人员是大名鼎鼎的Doug Lea,你觉得他开发的代码怎么会允许出现这种问题?


这个问题很棘手,因为它躺在角落里,程序正常运行的时候,它并不会出来作祟。

问题分析

接下来我们来看一下java中的线程池是如何运行我们提交的任务的,详细流程比较复杂,这里我们不关注,我们只关注任务执行的部分。java中的线程池用的是ThreadPoolExecutor,真正执行代码的部分是runWorker方法:final void runWorker(Worker w)

https://img1.sycdn.imooc.com//5d2b42a10001b36c10800780.jpg

可以看到,程序会捕获包括Error在内的所有异常,并且在程序最后,将出现过的异常和当前任务传递给afterExecute方法。

而ThreadPoolExecutor中的afterExecute方法是没有任何实现的。

 protected void afterExecute(Runnable r, Throwable t) { }

存在问题

想象下ThreadPoolExecutor这种处理方式会有什么问题?

这样做能够保证我们提交的任务抛出了异常不会影响其他任务的执行,同时也不会对用来执行该任务的线程产生任何影响。


问题就在afterExecute方法上, 这个方法没有做任何处理,所以如果我们的任务抛出了异常,我们也无法立刻感知到。  即使感知到了,也无法查看异常信息。


所以,作为一名好的开发者,是不应该允许这种情况出现的。


如何避免这种问题

思路很简单。

1、在提交的任务中将异常捕获并处理,不抛给线程池。

2、异常抛给线程池,但是我们要及时处理抛出的异常。

直接catch

第一种思路很简单,就是我们提交任务的时候,将所有可能的异常都Catch住,并且自己处理。

说白了就是把业务逻辑都trycatch起来。
但是这种思路的缺点就是:
1)所有的不同任务类型都要trycatch,增加了代码量。
2)不存在checkedexception的地方也需要都trycatch起来,代码丑陋。

线程池实现

第二种思路就可以避免上面的两个问题。

第二种思路又有以下四种实现方式

自定义线程池

自定义线程池,继承ThreadPoolExecutor并复写其afterExecute(Runnable r, Throwable t)方法。

https://img1.sycdn.imooc.com//5d2b42bd0001551610801055.jpg

实现Thread.UncaughtExceptionHandler接口

实现Thread.UncaughtExceptionHandler接口,
实现void uncaughtException(Thread t, Throwable e);方法,
并将该handler传递给线程池的ThreadFactory

https://img1.sycdn.imooc.com//5d2b42ce00010d4010801186.jpg

继承ThreadGroup

覆盖其uncaughtException方法。(与第二种方式类似,因为ThreadGroup类本身就实现了Thread.UncaughtExceptionHandler接口)

尤其注意:上面三种方式针对的都是通过execute(xx)的方式提交任务,如果你提交任务用的是submit()方法,那么上面的三种方式都将不起作用,而应该使用下面的方式

https://img1.sycdn.imooc.com//5d2b42ee00016b9010801015.jpg

采用Future模式

如果提交任务的时候使用的方法是submit,那么该方法将返回一个Future对象,所有的异常以及处理结果都可以通过future对象获取。
采用Future模式,将返回结果以及异常放到Future中,在Future中处理

https://img1.sycdn.imooc.com//5d2b42ff0001aae110800718.jpg

总结

文章探讨了从用户层面的代码到线程池层面的各种改造方法,力求让业务代码更加健壮可控。异常处理是java中非常重要的流程,但是线程池的默认操作,会使的这些内容被静悄悄的忽略,这在某些情况下是致命的

點擊查看更多內(nèi)容
2人點贊

若覺得本文不錯,就分享一下吧!

評論

作者其他優(yōu)質(zhì)文章

正在加載中
JAVA開發(fā)工程師
手記
粉絲
4552
獲贊與收藏
3234

關(guān)注作者,訂閱最新文章

閱讀免費(fèi)教程

感謝您的支持,我會繼續(xù)努力的~
掃碼打賞,你說多少就多少
贊賞金額會直接到老師賬戶
支付方式
打開微信掃一掃,即可進(jìn)行掃碼打賞哦
今天注冊有機(jī)會得

100積分直接送

付費(fèi)專欄免費(fèi)學(xué)

大額優(yōu)惠券免費(fèi)領(lǐng)

立即參與 放棄機(jī)會
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號

舉報

0/150
提交
取消