日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java runnable 异常_JAVA 线程中的异常捕获

發布時間:2024/1/23 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java runnable 异常_JAVA 线程中的异常捕获 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在java多線程程序中,所有線程都不允許拋出未捕獲的checked exception(比如sleep時的InterruptedException),也就是說各個線程需要自己把自己的checked exception處理掉。這一點是通過java.lang.Runnable.run()方法聲明(因為此方法聲明上沒有throw exception部分)進行了約束。但是線程依然有可能拋出unchecked exception(如運行時異常),當此類異常跑拋出時,線程就會終結,而對于主線程和其他線程完全不受影響,且完全感知不到某個線程拋出的異常(也是說完全無法catch到這個異常)。JVM的這種設計源自于這樣一種理念:“線程是獨立執行的代碼片斷,線程的問題應該由線程自己來解決,而不要委托到外部?!被谶@樣的設計理念,在Java中,線程方法的異常(無論是checked還是unchecked exception),都應該在線程代碼邊界之內(run方法內)進行try catch并處理掉.換句話說,我們不能捕獲從線程中逃逸的異常。

看下面的例子:

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ExceptionThread implements Runnable {

@Override

public void run() {

throw new RuntimeException("這個線程就干了這么一件事,拋出一個運行時異常");

}

public static void main(String[] args) {

try {

ExecutorService exec = Executors.newCachedThreadPool();

exec.execute(new ExceptionThread());

System.out.println("該干嘛干嘛去");

} catch (RuntimeException e) {

System.out.println("能不能捕獲到異常?");

}

}

}

運行結果:

該干嘛干嘛去

Exception in thread "pool-1-thread-1" java.lang.RuntimeException: 這個線程就干了這么一件事,拋出一個運行時異常

at ExceptionThread.run(ExceptionThread.java:8)

at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)

at java.lang.Thread.run(Thread.java:619)

從運行結果中,我們可以看到的是,這個異常在main線程中沒有catch到,即

System.out.println("能不能捕獲到異常?");

永遠不會執行到。

問題來了,我們如果需要捕獲其線程的unchecked異常時該怎么辦?Java SE5之后,我們可以通過Executor來解決這個我問題。為了解決這個問題,我們需要修改Executor產生線程的方式。Thread.UncaughtExceptionHandler是java SE5中的新接口,它允許我們在每一個Thread對象上添加一個異常處理器。(UncaughtExceptionHandler)。Thread.UncaughtExceptionHandler.uncaughtException()方法會在線程因未捕獲的異常而面臨死亡時被調用。下面這個例子簡單的演示了如何使用UncaughtExceptionHandler

import java.lang.Thread.UncaughtExceptionHandler;

/**

* 用于捕獲異常---捕獲的是uncheckedException

*

* @author February30th

*

*/

public class MyUnchecckedExceptionhandler implements UncaughtExceptionHandler {

@Override

public void uncaughtException(Thread t, Throwable e) {

System.out.println("捕獲到異常:" + e);

}

}

import java.util.concurrent.ThreadFactory;

public class HandlerThreadFactory implements ThreadFactory {

@Override

public Thread newThread(Runnable r) {

System.out.println("創建一個新的線程");

Thread t = new Thread(r);

t.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());

System.out.println("eh121 = " + t.getUncaughtExceptionHandler());

return t;

}

}

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

public class ThreadExceptionTest {

/**

* @param args

*/

public static void main(String[] args) {

//下面有3中方式來執行線程。

//第1種按照普通的方式。這是能捕獲到異常

Thread t = new Thread(new ExceptionThread2());

t.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());

t.start();

//第2種按照現成池,直接按照thread方式,此時不能捕獲到異常,為什么呢?因為在下面代碼中創建了一個線程,且設置了異常處理器,

//但是呢,在我們線程池中會重設置新的Thread對象,而這個Thread對象沒有設置任何異常處理器,換句話說,我們在線程池外對線程做的

//任何操作都是沒有用的

ExecutorService exec1 = Executors.newCachedThreadPool();

Runnable runnable = new ExceptionThread2();

Thread t1 = new Thread(runnable);

t1.setUncaughtExceptionHandler(new MyUnchecckedExceptionhandler());

exec1.execute(runnable);

//第3種情況一樣的,也是走的線程池,但是呢是通過ThreadFactory方式,在ThreadFactory中會對線程做一些控制,可以設置異常處理器

//此時是可以捕獲異常的。

ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());

exec.execute(new ExceptionThread2());

}

}

運行結果

創建一個新的線程

eh121 = MyUnchecckedExceptionhandler@1b8e059

run() byThread[Thread-0,5,main]

eh=MyUnchecckedExceptionhandler@1b8e059

捕獲到異常:java.lang.RuntimeException: 拋出運行時異常

從上述的運行結果中可以看到,未捕獲的異常是通過uncaughtException來捕獲的。

按照上述的實例,我們可以按照具體的情況,逐個地設置處理器。但是如果我們知道將要在代碼的所有地方都是用相同的異常處理器,那么更簡單的方式是在Thread類中設置一個靜態域,并將這個處理器設置為默認的未捕獲異常處理器。看下面的例子:

Thread.setDefaultUncaughtExceptionHandler(newMyUnchecckedExceptionhandler());

ExecutorService exec = Executors.newCachedThreadPool(new HandlerThreadFactory());

exec.execute(new ExceptionThread2());

這個默認的處理器只有在線程不存在非默認的異常處理器時才會調用。 在運行時,系統會檢查線程是否有屬于自己的異常處理器,如果發現沒有,就去檢查相應的線程組是否有專有的異常處理器,如果發現也沒有,再調用默認的異常處理器。

摘自:http://www.cnblogs.com/chenfei0801/archive/2013/04/23/3039286.html

總結

以上是生活随笔為你收集整理的java runnable 异常_JAVA 线程中的异常捕获的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。