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