亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

在Java子線程中怎么對異常進行處理

發布時間:2020-12-07 16:14:33 來源:億速云 閱讀:117 作者:Leah 欄目:編程語言

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

常見錯誤

也許有人會覺得,很簡單嘛,直接在父線程啟動子線程的地方try ... catch一把就可以了,其實這是不對的。

原因分析

讓我們回憶一下Runnable接口的run方法的完整簽名,因為沒有標識throws語句,所以方法是不會拋出checked異常的。至于RuntimeException這樣的unchecked異常,由于新線程由JVM進行調度執行,如果發生了異常,也不會通知到父線程。

public abstract void run()

解決辦法

那么,如何在父線程中捕獲來自子線程的異常呢?樓主想到了3種常用方法,分享給大家。

方法一:子線程中try... catch...

最簡單有效的辦法,就是在子線程的方法中,把可能發生異常的地方,用try ... catch ... 語句包起來。子線程代碼:

public class ChildThread implements Runnable {
 public void run() {
  doSomething1();
  try {
   // 可能發生異常的方法
   exceptionMethod();
  } catch (Exception e) {
   // 處理異常
   System.out.println(String.format("handle exception in child thread. %s", e));
  }
  doSomething2();
 }
}

方法二:為線程設置異常處理器UncaughtExceptionHandler

為線程設置異常處理器。具體做法可以是以下幾種:

(1)Thread.setUncaughtExceptionHandler設置當前線程的異常處理器

(2)Thread.setDefaultUncaughtExceptionHandler為整個程序設置默認的異常處理器如果當前線程有異常處理器(默認沒有),則優先使用該UncaughtExceptionHandler類;否則,如果當前線程所屬的線程組有異常處理器,則使用線程組的ExceptionHandler;否則,使用全局默認的DefaultUncaughtExceptionHandler;如果都沒有的話,子線程就會退出。

注意:子線程中發生了異常,如果沒有任何類來接手處理的話,是會直接退出的,而不會留下打印任何日志。所以,如果什么都不做的話,是會出現子線程任務既沒執行,也沒有任何日志提示的“詭異”現象的。

設置當前線程的異常處理器:

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));
  }
 }
}

或者,設置所有線程的默認異常處理器

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之后可以獲得一個線程執行結果的Future對象,而如果子線程中發生了異常,通過future.get()獲取返回值時,可以捕獲到ExecutionException異常,從而知道子線程中發生了異常。

子線程代碼:

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

關于在Java子線程中怎么對異常進行處理就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

青神县| 峨眉山市| 达拉特旗| 和平区| 鹤庆县| 满城县| 盘锦市| 闽侯县| 屏南县| 饶河县| 黎城县| 民乐县| 惠来县| 新余市| 澳门| 临湘市| 济阳县| 祥云县| 莆田市| 葫芦岛市| 屏东市| 南漳县| 邯郸市| 山丹县| 奈曼旗| 濉溪县| 永靖县| 固阳县| 锡林浩特市| 连州市| 汾阳市| 榆树市| 吉安市| 安泽县| 灵丘县| 隆回县| 沂水县| 漳平市| 凤阳县| 荆门市| 恭城|