程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 0040 Java學習筆記-多線程-線程run()辦法中的異常

0040 Java學習筆記-多線程-線程run()辦法中的異常

編輯:關於JAVA

0040 Java學習筆記-多線程-線程run()辦法中的異常。本站提示廣大學習愛好者:(0040 Java學習筆記-多線程-線程run()辦法中的異常)文章只能為提供參考,不一定能成為您想要的結果。以下是0040 Java學習筆記-多線程-線程run()辦法中的異常正文


run()與異常

  • 不論是Threade還是Runnable的run()辦法都沒有定義拋出異常,也就是說一條線程外部發作的checked異常,必需也只能在外部用try-catch處置掉,不能往外拋,由於線程是一個獨立運轉的代碼片段,它的問題不能影響到其他線程
  • 假如run()外部拋出一個unchecked異常,這個線程能夠會終止運轉,這個異常也不能被主線程捕捉,也影響不到其他線程的執行,比方上面的示例:
package testpack;

import java.io.IOException;

public class Test2  { 
    public static void main(String[] args) throws InterruptedException{ 
        try {
            new A("異常線程").start();
        } catch(RuntimeException re) {
            System.out.println("主線程捕捉到子線程的異常:");    //這裡不會被執行,主線程不能捕捉子線程的unchecked異常
            re.printStackTrace();
        }
        Thread.sleep(5);
        System.out.println("主線程照常執行");                    //子線程終止,不影響主線程的正常執行
    }
}
class A extends Thread{
    A(String name){
        super(name);
    }
    public void run(){
        System.out.println("run()辦法運轉...");
        for (int i=0;i<10;i++) {
            System.out.println(getName()+" 輸入:"+i);
            if (i==3) {
                throw new RuntimeException("run外部拋出Runtime異常");  //第3個循環時,拋出一個unchecked異常
            }
        }
        
    }
}

輸入:

run()辦法運轉...
異常線程 輸入:0
異常線程 輸入:1
異常線程 輸入:2
異常線程 輸入:3
Exception in thread "異常線程" java.lang.RuntimeException: run外部拋出Runtime異常 at testpack.A.run(Test2.java:26) //子線程拋出unchecked異常,不能被主線程catch到,線程終止執行。這裡的輸入來源於ThreadGroup的uncaughtException()辦法
主線程照常執行 //子線程終止後,不影響主線程執行

Thread.UncaughtExceptionHandler異常處置器

  • Thread有一個靜態外部接口,UncaughtExceptionHandler,該接口用來定義未處置異常處置器,只要一個辦法void uncaughtException(Thread t,Throwable e)
  • 可以自己定義一個線程處置器,然後將其綁定到一個線程實例、Thread上,ThreadGroup曾經完成了void uncaughtException(Thread t,Throwable e)辦法,假如要更改的話,就承繼ThreadGroup類然後重寫該辦法
  • 將一個未處置異常處置器綁到線程對象上:調用該線程對象的setUncaughtExceptionHandler()
  • 綁到Thread上:調用Thread的靜態辦法Thread.setDefaultUncaughtExceptionHandler()

未處置異常處置器的調用順序

  • 先找該線程實例能否有處置器
  • 再交給所屬線程組的uncaughtException()辦法
    • 嚴厲的說,這個辦法只是個中介,分上面三步走
    • 假如還有父線程組,則交給父線程組的uncaughtException()辦法
    • 交給Thread的Thread.getDefaultUncaughtExceptionHandler()前往的Thread默許處置器
    • 最後看該線程是不是ThreadDeath對象,是的話,不做處置;不是的話,先用System.err輸入哪個線程上有Exception,然後將異常跟蹤站信息打印到System.err,線程完畢
  • 看示例:
package testpack;

import java.lang.Thread.UncaughtExceptionHandler;

public class Test2  { 
    public static void main(String[] args) throws InterruptedException{ 
        ExHandler eh1=new ExHandler("Thread默許異常處置器");  //定義一個異常處置器,前面綁到Thread上
        ExHandler eh2=new ExHandler("線程實例異常處置器");    //前面綁到線程實例上
        Thread.setDefaultUncaughtExceptionHandler(eh1);       //將eh1處置器綁到Thread上
        A a=new A("異常線程");
        a.setUncaughtExceptionHandler(eh2);                   //標志㈠。將eh2綁到線程實例上
        a.start();
        
    }
}
class A extends Thread{
    A(ThreadGroup tg,String name){
        super(tg,name);
    }
    A(String name){
        super(name);
    }
    public void run(){
        System.out.println("run()辦法運轉...");
        for (int i=0;i<10;i++) {
            System.out.println(getName()+" 輸入:"+i);
            if (i==3) {
                int x=5/0;                                       //i==3時,拋出unchecked異常
            }
        }
        
    }
}
class ExHandler implements UncaughtExceptionHandler{              //自定義一個未處置異常處置器
    private String name;
    ExHandler(String name){
        this.name=name;
    }
    public void uncaughtException (Thread t,Throwable e){
        System.out.println("這是:"+name);
        System.out.println("線程: "+t.getName()+" 異常: "+e.getMessage());
    }
} 

輸入:

run()辦法運轉...
異常線程 輸入:0
異常線程 輸入:1
異常線程 輸入:2
異常線程 輸入:3
這是:線程實例異常處置器 //調用了線程實例上的異常處置器
線程: 異常線程 異常: / by zero //順序完畢

將標志㈠處的代碼正文掉,輸入如下:

run()辦法運轉...
異常線程 輸入:0
異常線程 輸入:1
異常線程 輸入:2
異常線程 輸入:3
這是:Thread默許異常處置器 //調用了Thread上的默許處置器,“異常線程”屬於main線程組,父線程組是system,
線程: 異常線程 異常: / by zero

其他

  • 最近發現一個做筆記的中央,螞蟻筆記:https://leanote.com,支持Markdown,還可以把一篇筆記或一個筆記本地下為博客,可以綁定二級域名或許自定義域名,可以導出為PDF,支持團隊協作,甚至是開源的,可以將其部署在自己的服務器上,是一個挺不錯的使用
  • 本篇筆記也發布在leanote:在這裡
  • 這是我的約請鏈接,假如想注冊,可以經過該鏈接,你我都可以取得30天的旗艦版時間
    
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved