程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JAVA Thread線程異常監控

JAVA Thread線程異常監控

編輯:關於JAVA

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 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved