摘要:在之前,不能為線程多帶帶設(shè)置或指定一個(gè)默認(rèn)的,為了設(shè)置,需要繼承并覆寫方法。幸運(yùn)的是后線程提供了一個(gè)方法,用來(lái)捕獲并處理因線程中拋出的未知異常,以避免程序終止。
概述在單線程的開發(fā)過(guò)程中,通常采用try-catch的方式進(jìn)行異常捕獲,但是這種方式在多線程環(huán)境中會(huì)顯得無(wú)能為力,而且還有可能導(dǎo)致一些問(wèn)題的出現(xiàn),比如發(fā)生異常的時(shí)候不能及時(shí)回收系統(tǒng)資源,或者無(wú)法及時(shí)關(guān)閉當(dāng)前的連接...
Java中有兩種異常,即已知異常(編輯器會(huì)提示捕獲或者拋出)和未知異常(特殊情況下發(fā)生),由于線程中的run()方法是不接受拋出語(yǔ)句的(只能內(nèi)部捕獲),所以在面對(duì)未知異常的情況,線程默認(rèn)的會(huì)將堆棧跟蹤信息輸出到控制臺(tái)中(或者記錄到錯(cuò)誤日志文件中)然后退出程序。
在JDK1.5之前,不能為線程多帶帶設(shè)置或指定一個(gè)默認(rèn)的UncaughtExceptionHandler,為了設(shè)置UncaughtExceptionHandler,需要繼承ThreadGroup并覆寫uncaughtException方法。 幸運(yùn)的是JDK1.5后線程提供了一個(gè)setUncaughtExceptionHandler方法,用來(lái)捕獲并處理因線程中拋出的未知異常,以避免程序終止。
案例1.首先模擬一個(gè)連接池,提供
class ConnectionPool { static void create() { System.out.println("初始化連接池..."); } static void close() { System.out.println("關(guān)閉連接池..."); } }
2.為了測(cè)試需要,只是簡(jiǎn)單模擬了一個(gè)異常
public static void main(String[] args) { ConnectionPool.create(); try { //有個(gè)任務(wù)需要異步執(zhí)行 Thread thread = new Thread(() -> System.out.println(Integer.parseInt("ABC")), "T2"); thread.start(); } catch (Exception e) { ConnectionPool.close(); } }
分析: 從日志中,并未發(fā)現(xiàn)關(guān)閉資源應(yīng)有的日志輸出,很明顯try-catch沒(méi)有起作用,因?yàn)樵?b>main函數(shù)中他是主線程,當(dāng)thread.start()之后,主線程的代碼與子線程就沒(méi)半毛錢關(guān)系了,所以發(fā)生在子線程內(nèi)部的錯(cuò)誤無(wú)法捕獲到。
解決方案使用UncaughtExceptionHandler,這里為了偷懶使用了lambda簡(jiǎn)化了匿名內(nèi)部類的寫法(也可以實(shí)現(xiàn)UncaughtExceptionHandler)
public static void main(String[] args) { ConnectionPool.create(); Thread thread = new Thread(() -> System.out.println(Integer.parseInt("ABC")), "T1"); thread.start(); thread.setUncaughtExceptionHandler((t, e) -> { System.out.println("[線程] - [" + t.getName() + "] - [消息] - [" + e.getMessage() + "]"); ConnectionPool.close(); }); }
分析: 從日志中可以發(fā)現(xiàn)錯(cuò)誤信息被我們捕獲了,并且可以成功釋放資源!使用UncaughtExceptionHandler,可以捕獲到未知異常且記錄下自定義的日志(默認(rèn)拋出堆棧信息),具體在Zookeeper中就有使用過(guò),源碼為:ZookeeperThread,ZooKeeperCriticalThread,有興趣可以去看看...
- 說(shuō)點(diǎn)什么全文代碼:https://gitee.com/battcn/battcn-concurent/tree/master/Chapter1-1/battcn-thread/src/main/java/com/battcn/chapter11
個(gè)人QQ:1837307557
battcn開源群(適合新手):391619659
微信公眾號(hào):battcn(歡迎調(diào)戲)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/67749.html
摘要:在前面的文章中介紹過(guò)觀察者模式及并發(fā)編程的基礎(chǔ)知識(shí),為了讓大家更好的了解觀察者模式故而特意寫了這篇番外概述在多線程下我們需要知道當(dāng)前執(zhí)行線程的狀態(tài)是什么比如運(yùn)行,關(guān)閉,異常等狀態(tài)的通知,而且不僅僅是更新當(dāng)前頁(yè)面。 在前面的文章中介紹過(guò) 觀察者模式 及 并發(fā)編程的基礎(chǔ)知識(shí),為了讓大家更好的了解觀察者模式故而特意寫了這篇番外.. 概述 在Java多線程下,我們需要知道當(dāng)前執(zhí)行線程的狀態(tài)是...
摘要:的作用是為其他線程的運(yùn)行提供服務(wù),比如說(shuō)線程。在某些平臺(tái)上,指定一個(gè)較高的參數(shù)值可能使線程在拋出之前達(dá)到較大的遞歸深度。參數(shù)的值與最大遞歸深度和并發(fā)程度之間的關(guān)系細(xì)節(jié)與平臺(tái)有關(guān)。 今天研究了下Java線程基礎(chǔ)知識(shí),發(fā)現(xiàn)以前太多知識(shí)知識(shí)略略帶過(guò)了,比較說(shuō)Java的線程機(jī)制,在Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護(hù)線程),以及構(gòu)造器中的s...
摘要:在這個(gè)示例中我們使用了一個(gè)單線程線程池的。在延遲消逝后,任務(wù)將會(huì)并發(fā)執(zhí)行。這是并發(fā)系列教程的第一部分。第一部分線程和執(zhí)行器第二部分同步和鎖第三部分原子操作和 Java 8 并發(fā)教程:線程和執(zhí)行器 原文:Java 8 Concurrency Tutorial: Threads and Executors 譯者:BlankKelly 來(lái)源:Java8并發(fā)教程:Threads和Execut...
摘要:考慮大量線程運(yùn)行在一次計(jì)算的不同部分的情形。一旦所有的線程都到達(dá)了這個(gè)柵欄,柵欄就撤銷,線程可以繼續(xù)運(yùn)行。那些已經(jīng)在等待的線程立即中止的調(diào)用。如果在執(zhí)行屏障操作過(guò)程中發(fā)生異常,則該異常將傳播到當(dāng)前線程中,并將置于損壞狀態(tài)。 【同步器 java.util.concurrent包包含幾個(gè)能幫助人們管理相互合作的線程集的類。這些機(jī)制具有為線程直間的共用集結(jié)點(diǎn)模式提供的‘預(yù)制功能’。如果有一個(gè)...
摘要:一般差異簡(jiǎn)單來(lái)說(shuō),是一個(gè)用于線程同步的實(shí)例方法。暫停當(dāng)前線程,不釋放任何鎖。用來(lái)線程間通信,使擁有該對(duì)象鎖的線程等待直到指定時(shí)間或。執(zhí)行對(duì)該對(duì)象加的同步代碼塊。 在JAVA的學(xué)習(xí)中,不少人會(huì)把sleep和wait搞混,認(rèn)為都是做線程的等待,下面主要介紹下這倆者是什么,及了解它們之間的差異和相似之處。 一般差異 簡(jiǎn)單來(lái)說(shuō),wait()是一個(gè)用于線程同步的實(shí)例方法。因?yàn)槎x在java.l...
閱讀 2748·2021-10-22 09:55
閱讀 2149·2021-09-27 13:35
閱讀 1335·2021-08-24 10:02
閱讀 1633·2019-08-30 15:55
閱讀 1273·2019-08-30 14:13
閱讀 3534·2019-08-30 13:57
閱讀 2046·2019-08-30 11:07
閱讀 2534·2019-08-29 17:12