簡體   English   中英

在Thread.run中處理java異常

[英]handle java exception in Thread.run

我有一個擴展Thread的內部類

private class TestStart extends Thread {
    public void run() {
        try {
            startServer();
        }
        catch (Exception e) {
            /// How to handle it?
        }
    }
} 

主線程中的調用者:

public void start() throws Exception {
    Thread st = new TestStart();
    st.start();
}

方法startServer()通過其API拋出異常,因此我必須使用try-catch,因為Thread.run()不會在方法定義中“拋出”異常。 我需要將捕獲的異常冒泡到主線程中來處理它。 有一個簡單的方法嗎? 謝謝

如果您使用ExecutorService而不是使用原始線程,則可以通知您未捕獲的異常:

class MyCallable implements Callable<Void> {
  @Override public Void call() throws Exception {
    // Do something - you don't need to catch Exception as Callable throws it.
    // ...

    return null;  // A return is necessary from a Callable.
  }
}

在某處創建執行程序服務,例如:

ExecutorService executor = Executors.newFixedThreadPool(1);

然后,在啟動線程的代碼中:

Future<?> future = executor.submit(new MyCallable());

try {
  future.get();  // Blocks until the Callable completes.
} catch (ExecutionException e) {
  // You reach here if an exception is thrown in the Callable -
  // The exception is accessible via e.getCause().
}

在Thread上設置一個新的異常處理程序。

   st.setDefaultUncaughtExceptionHandler(new Thread.
             UncaughtExceptionHandler() {
               public void uncaughtException(Thread t, Throwable e) {
               System.out.println(t + " throws exception: " + e);
             }
   });

並在開始之前放置代碼();

有一些可能的解決方案。 例如:

  1. 使用setUncaughtExceptionHandler()/ setDefaultUncaughtExceptionHandler()並更改你的try / catch

     try { startServer(); } catch (RuntimeException e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } 
  2. 或者使用自定義偵聽器

     private class TestStart extends Thread { private final ServerStateListener lnr; TestStart(ServerStateListener lnr) { this.lnr = lnr; } public void run() { try { startServer(); lnr.onServerStarted(); } catch (Exception e) { lnr.onServerStoppedByError(e); } } } 
  3. 或者只是保存Exception並在.join之后讀取它

     private class TestStart extends Thread { private Exception error; // if you start and join and read this property within one thread, you don't need to use volatile, otherwise do it for safe publication public void run() { try { startServer(); } catch (Exception e) { error = e; } } public Exception getError() { return error; } } 
  4. 或者使用ExecutorService / Callable而不是你自己的線程,正如Andy建議的那樣。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM