处理在单独线程中抛出的exception的最佳方法是什么?

我正在开发一个J2ME项目,该项目为许多任务(如下载HTTP内容)生成工作线程。 基本的线程布局类似于大多数Java应用程序 – 有一个主UI线程和工作线程产生在幕后做东西。 我的问题是处理工作线程中发生的exception的最佳方法是什么?

我通常坚持设计理由,即大多数例外情况应尽可能渗透。 当我编写单线程应用程序时,我常常将exception一直渗透到UI层,然后在错误对话框中将它们报告给用户。 multithreading应用程序是否有类似的做法? 对我来说最直观的事情是在Thread.run()中捕获exception,然后在UI线程上调用invokeLater以在对话框中报告它。 我在这里看到的问题是,在工作线程之外过早死亡,这种方法并没有真正通知UI线程有错误。 我没有看到一个明确的方法来跨线程抛出exception可以这么说。

谢谢,安迪

您不应该将UI代码堵塞到您的工作人员中!

/** * TWO CHOICES: * - Monitor your threads and report errors, * - setup a callback to do something. */ public class ThreadExceptions { /** Demo of {@link RunnableCatch} */ public static void main(String[] argv) throws InterruptedException { final Runnable bad = new NaughtyThread(); // safe1 doesnt have a callback final RunnableCatch safe1 = new RunnableCatch(bad); // safe2 DOES have a callback final RunnableCatch safe2 = new RunnableCatch(bad, new RunnableCallback() { public void handleException(Runnable runnable, Exception exception) { System.out.println("Callback handled: " + exception.getMessage()); exception.printStackTrace(); } }); final Thread t1 = new Thread(safe1, "myThread"); final Thread t2 = new Thread(safe2, "myThread"); t1.start(); t2.start(); t1.join(); t2.join(); if (safe1.getException() != null) { System.out.println("thread finished with exceptions"); safe1.getException().printStackTrace(); } System.out.println("done"); } } /** Throws an exception 50% of the time */ class NaughtyThread implements Runnable { public void run() { try { if (Math.random() > .5) { throw new RuntimeException("badness"); } } finally { System.out.println("ran"); } } } /** Called when an exception occurs */ interface RunnableCallback { void handleException(Runnable runnable, Exception exception); } /** * Catches exceptions thrown by a Runnable, * so you can check/view them later and/or * deal with them from some callback. */ class RunnableCatch implements Runnable { /** Proxy we will run */ private final Runnable _proxy; /** Callback, if any */ private final RunnableCallback _callback; /** @guarded-by(this) */ private Exception _exception; public RunnableCatch(final Runnable proxy) { this(proxy, null); } public RunnableCatch(final Runnable proxy, RunnableCallback target) { _proxy = proxy; _callback = target; } public void run() { try { _proxy.run(); } catch (Exception e) { synchronized (this) { _exception = e; } if (_callback != null) { _callback.handleException(_proxy, e); } } } /** @return any exception that occured, or NULL */ public synchronized Exception getException() { return _exception; } } 

除了Stuph之外的另一个选择是在本地线程中设置exception。 如果在清除该exception之前发生另一个exception,则发生断言。 这至少让某人有机会注意到exception并处理它。