這篇文章給大家介紹在Java子線程中怎么對異常進行處理,內(nèi)容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

成都創(chuàng)新互聯(lián)公司專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于成都網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、赤峰林西網(wǎng)絡(luò)推廣、微信小程序定制開發(fā)、赤峰林西網(wǎng)絡(luò)營銷、赤峰林西企業(yè)策劃、赤峰林西品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎;成都創(chuàng)新互聯(lián)公司為所有大學(xué)生創(chuàng)業(yè)者提供赤峰林西建站搭建服務(wù),24小時服務(wù)熱線:18980820575,官方網(wǎng)址:www.chinadenli.net
常見錯誤
也許有人會覺得,很簡單嘛,直接在父線程啟動子線程的地方try ... catch一把就可以了,其實這是不對的。
原因分析
讓我們回憶一下Runnable接口的run方法的完整簽名,因為沒有標(biāo)識throws語句,所以方法是不會拋出checked異常的。至于RuntimeException這樣的unchecked異常,由于新線程由JVM進行調(diào)度執(zhí)行,如果發(fā)生了異常,也不會通知到父線程。
public abstract void run()
解決辦法
那么,如何在父線程中捕獲來自子線程的異常呢?樓主想到了3種常用方法,分享給大家。
方法一:子線程中try... catch...
最簡單有效的辦法,就是在子線程的方法中,把可能發(fā)生異常的地方,用try ... catch ... 語句包起來。子線程代碼:
public class ChildThread implements Runnable {
public void run() {
doSomething1();
try {
// 可能發(fā)生異常的方法
exceptionMethod();
} catch (Exception e) {
// 處理異常
System.out.println(String.format("handle exception in child thread. %s", e));
}
doSomething2();
}
}方法二:為線程設(shè)置異常處理器UncaughtExceptionHandler
為線程設(shè)置異常處理器。具體做法可以是以下幾種:
(1)Thread.setUncaughtExceptionHandler設(shè)置當(dāng)前線程的異常處理器
(2)Thread.setDefaultUncaughtExceptionHandler為整個程序設(shè)置默認的異常處理器如果當(dāng)前線程有異常處理器(默認沒有),則優(yōu)先使用該UncaughtExceptionHandler類;否則,如果當(dāng)前線程所屬的線程組有異常處理器,則使用線程組的ExceptionHandler;否則,使用全局默認的DefaultUncaughtExceptionHandler;如果都沒有的話,子線程就會退出。
注意:子線程中發(fā)生了異常,如果沒有任何類來接手處理的話,是會直接退出的,而不會留下打印任何日志。所以,如果什么都不做的話,是會出現(xiàn)子線程任務(wù)既沒執(zhí)行,也沒有任何日志提示的“詭異”現(xiàn)象的。
設(shè)置當(dāng)前線程的異常處理器:
public class ChildThread implements Runnable {
private static ChildThreadExceptionHandler exceptionHandler;
static {
exceptionHandler = new ChildThreadExceptionHandler();
}
public void run() {
Thread.currentThread().setUncaughtExceptionHandler(exceptionHandler);
System.out.println("do something 1");
exceptionMethod();
System.out.println("do something 2");
}
public static class ChildThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.out.println(String.format("handle exception in child thread. %s", e));
}
}
}或者,設(shè)置所有線程的默認異常處理器
public class ChildThread implements Runnable {
private static ChildThreadExceptionHandler exceptionHandler;
static {
exceptionHandler = new ChildThreadExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(exceptionHandler);
}
public void run() {
System.out.println("do something 1");
exceptionMethod();
System.out.println("do something 2");
}
private void exceptionMethod() {
throw new RuntimeException("ChildThread exception");
}
public static class ChildThreadExceptionHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.out.println(String.format("handle exception in child thread. %s", e));
}
}
}命令行輸出:do something 1
handle exception in child thread. java.lang.RuntimeException: ChildThread exception
方法三,通過Future的get方法捕獲異常
使用線程池提交一個能獲取到返回信息的方法,也就是ExecutorService.submit(Callable)在submit之后可以獲得一個線程執(zhí)行結(jié)果的Future對象,而如果子線程中發(fā)生了異常,通過future.get()獲取返回值時,可以捕獲到ExecutionException異常,從而知道子線程中發(fā)生了異常。
子線程代碼:
public class ChildThread implements Callable {
public Object call() throws Exception {
System.out.println("do something 1");
exceptionMethod();
System.out.println("do something 2");
return null;
}
private void exceptionMethod() {
throw new RuntimeException("ChildThread1 exception");
}
}父線程代碼:
public class Main {
public static void main(String[] args) {
ExecutorService executorService = Executors.newFixedThreadPool(8);
Future future = executorService.submit(new ChildThread());
try {
future.get();
} catch (InterruptedException e) {
System.out.println(String.format("handle exception in child thread. %s", e));
} catch (ExecutionException e) {
System.out.println(String.format("handle exception in child thread. %s", e));
} finally {
if (executorService != null) {
executorService.shutdown();
}
}
}
}命令行輸出:do something 1
handle exception in child thread. java.util.concurrent.ExecutionException: java.lang.RuntimeException: ChildThread1 exception
關(guān)于在Java子線程中怎么對異常進行處理就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
當(dāng)前標(biāo)題:在Java子線程中怎么對異常進行處理
本文地址:http://www.chinadenli.net/article36/geehpg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站收錄、電子商務(wù)、ChatGPT、網(wǎng)站改版、外貿(mào)建站、面包屑導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)