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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

捕获线程中的异常

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

為什么80%的碼農都做不了架構師?>>> ??

由于線程的本質特性,使得你不能捕獲從線程中逃逸的異常。一旦異常逃出任務的run()方法它就會向外傳播到控制臺,除非你采取特殊的步驟捕獲這種錯誤的異常。在Java SE5之前,你可以使用線程組來捕捉這種異常,但是有了Java SE5,就可以用Executor來解決這個問題了。

下面的任務總是會拋出一個異常,該異常會傳播到其run()方法的外部,并且main()展示了當你運行它時所發生的事情:

import?java.util.concurrent.ExecutorService; import?java.util.concurrent.Executors;public?class?ExceptionThread?implements?Runnable?{public?void?run()?{throw?new?RuntimeException();}public?static?void?main(String[]?args)?{ExecutorService?service?=?Executors.newCachedThreadPool();service.execute(new?ExceptionThread());} }

輸出如下:

Exception?in?thread?"pool-1-thread-1"?java.lang.RuntimeExceptionat?com.abc.thread.ExceptionThread.run(ExceptionThread.java:6)at?java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)at?java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)at?java.lang.Thread.run(Thread.java:745)

將main的主體放在try-catch語句塊中也是沒有作用的:

import?java.util.concurrent.ExecutorService; import?java.util.concurrent.Executors;public?class?ExceptionThread?implements?Runnable?{public?void?run()?{throw?new?RuntimeException();}public?static?void?main(String[]?args)?{try?{ExecutorService?service?=?Executors.newCachedThreadPool();service.execute(new?ExceptionThread());}?catch?(RuntimeException?e)?{System.out.println("Catched?Runtime?Exception.");}} }

這將產生于前面示例相同的結果:未捕獲的異常。

為了解決這個問題,我們要修改Executor產生線程的方式。Thread.UncaughtExceptionHandler是Java SE5中的新接口,它允許你在每個Thread對象上都附著一個異常處理器。Thread.UncaughtExceptionHandler.uncaughtException()會在線程因未捕獲的異常而臨近死亡時被調用。為了使用它,我們創建了一個新類型的ThreadFactory,它將在每個新創建的Thread對象上附著一個Thread.UncaughtExceptionHandler。

import?java.util.concurrent.ExecutorService; import?java.util.concurrent.Executors; import?java.util.concurrent.ThreadFactory;public?class?ExceptionThread2?implements?Runnable?{public?void?run()?{throw?new?RuntimeException("NullPointer");}public?static?void?main(String[]?args)?{ThreadFactory?tFactory?=?new?MyThreadFactory();ExecutorService?service?=?Executors.newCachedThreadPool(tFactory);Runnable?task?=?new?ExceptionThread2();service.execute(task);} }class?MyUncaughtExceptionHandler?implements?Thread.UncaughtExceptionHandler?{//?處理從線程里拋出來的異常。public?void?uncaughtException(Thread?t,?Throwable?e)?{System.out.println("Catched?Throwable:?"?+?e.getClass().getSimpleName()?+?",?"?+?e.getMessage());} }class?MyThreadFactory?implements?ThreadFactory?{//?重新組織創建線程的方式public?Thread?newThread(Runnable?r)?{Thread?t?=?new?Thread(r);//?為每一個線程都綁定一個異常處理器。t.setUncaughtExceptionHandler(new?MyUncaughtExceptionHandler());System.out.println("Thread["?+?t.getName()?+?"]?created.");return?t;} }

執行的結果如下:

可以看到,線程池中有2個線程,當一個線程發生異常時,該異常被捕捉了。

上面的示例使得你可以按照具體情況(在newThread()方法中使用if, case等語句)為每個線程逐個的設置處理器。如果你知道將要在代碼中處處使用相同的異常處理器,那么更簡單的方式是在Thread類中設置一個靜態域,并將這個處理器設置為默認的處理器即可:

import?java.util.concurrent.ExecutorService; import?java.util.concurrent.Executors;public?class?SettingDefaultHandler?{public?static?void?main(String[]?args)?{//?為線程設置默認的異常處理器。Thread.setDefaultUncaughtExceptionHandler(new?MyUncaughtExceptionHandler());ExecutorService?exec?=?Executors.newCachedThreadPool();exec.execute(new?ExceptionThread2());} }

這個處理器只有在不存在線程專有的未捕獲異常處理器的情況下才會被調用。系統會檢查線程專有版本,如果沒有發現,則檢查線程組是否有專有的uncaughtException()方法,如果也沒有,才會調用defaultUncaughtExceptionHandler。


轉載于:https://my.oschina.net/itblog/blog/502479

總結

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

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