JAVA Thread線程異常監控。本站提示廣大學習愛好者:(JAVA Thread線程異常監控)文章只能為提供參考,不一定能成為您想要的結果。以下是JAVA Thread線程異常監控正文
一、場景描繪:單線程順序可以用try...catch捕捉順序的異常,而在多線程順序的時分是無法運用try...catch捕捉。
示例1:多線程發作異常,無法運用try...catch捕捉問題
public class NoCaughtThread implements Runnable{ @Override public void run() { System.out.println(3 / 2); System.out.println(3 / 0); System.out.println(3 / 1); } public static void main(String[] args) { try { Thread thread = new Thread(new NoCaughtThread()); thread.start(); } catch (Exception e) { System.out.println("==Exception: " + e.getMessage()); } } }
運轉後果:
1
Exception in thread "Thread-0" java.lang.ArithmeticException: / by zero
at threadtest.NoCaughtThread.run(NoCaughtThread.java:7)
at java.lang.Thread.run(Thread.java:724)
顯然這並非順序設定異常捕捉,此時try...catch無法捕捉線程的異常。此時,假如線程由於異常而終止執即將無法檢測到異常。究其緣由Thread類run()辦法是不拋出任何反省型異常的,而本身卻能夠由於一個異常而被中止。
二、處理方式大致有兩種:① 在run()中設置對應的異常處置,自動辦法來處理未檢測異常;② Thread類API中提供Interface接口UncaughtExceptionHandler,該接口包括uncaughtException辦法,它能檢測出某個未捕捉的異常而終結的狀況;
示例2:自動的檢測異常
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class InitiativeCaught { public static void main(String[] args) { InitialtiveThread initialtiveThread = new InitialtiveThread() ; ExecutorService exec = Executors.newCachedThreadPool(); exec.execute(initialtiveThread); exec.shutdown(); } } class InitialtiveThread implements Runnable { @Override public void run() { Throwable thrown = null; try { System.out.println(3 / 2); System.out.println(3 / 0); System.out.println(3 / 1); } catch (Throwable e) { thrown = e; } finally { threadDeal(this, thrown); } } public void threadDeal(Runnable r, Throwable t) { System.out.println("==Exception: " + t.getMessage()); } }
運轉後果:
1
==Exception: / by zero
此時是自動捕捉異常並做處置,失掉想要的後果。
示例3:Thread類API中提供UncaughtExceptionHandler接口捕捉異常,要求檢測線程異常,發作異常設置為反復調用三次之後完畢線程。
import java.lang.Thread.UncaughtExceptionHandler; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadMonitor implements Runnable { private int data; // 可設置經過結構傳參 private int control = 0; private static final int MAX = 3; // 設置重試次數 public ThreadMonitor(int i) { this.data = i; } public ThreadMonitor() { // TODO Auto-generated constructor stub } @Override public void run() { Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread arg0, Throwable e) { // TODO Auto-generated method stub System.out.println("==Exception: " + e.getMessage()); String message = e.getMessage(); if( control==MAX ){ return ; }else if( "ok".equals(message) ){ return ; }else if ( "error".equals(message) ) { new Thread() { public void run() { try { System.out.println("開端睡眠。"); Thread.sleep(1 * 1000); control++ ; System.out.println("睡眠完畢,control: "+ control); myTask(data) ; } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); }else{ return ; } } }); myTask(data) ; } @SuppressWarnings("finally") public void myTask(int data){ boolean flag = true ; try { System.out.println(4 / data); } catch (Exception e) { flag = false ; } finally { if( flag ){ throw new RuntimeException("ok"); }else{ throw new RuntimeException("error"); } } } public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); ThreadMonitor threadMonitor = new ThreadMonitor(0); exec.execute(threadMonitor); exec.shutdown(); } }
運轉後果:
==Exception: error
開端睡眠。
睡眠完畢,control: 1
==Exception: error
開端睡眠。
睡眠完畢,control: 2
==Exception: error
開端睡眠。
睡眠完畢,control: 3
==Exception: error
此時,可以正常捕捉線程因除數為零形成的中綴。其中:
(1) 在Thread類API中提供Interface接口UncaughtExceptionHandler,該接口包括一個uncaughtException辦法,它能檢測出某個由於未捕捉的異常而終結的狀況。定義如下:
UncaughtExceptionHandler接口: public static interface Thread.UncaughtExceptionHandler
uncaughtException辦法: public void uncaughtException(Thread t, Throwable e)
(2) uncaughtException辦法會捕捉線程的異常,此時需求覆寫該辦法設定自定義的處置方式。
(3) 設置UncaughtExceptionHandler異常處置:
方式一:經過Thread提供的靜態static辦法,設置默許異常處置:public static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler ux)
方式二:經過辦法:public void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)
(4) UncaughtExceptionHandler異常處置需求設置在run()辦法內,否則無法捕捉到線程的異常。
(5) 參考鏈接:
JAVA下內存池啟動順序:http://www.cnblogs.com/zhujiabin/p/5404771.html
JAVA下多線程異常處置:http://blog.csdn.net/u013256816/article/details/50417822