处理在单独线程中抛出异常的最佳方法是什么? [英] What is the best approach to handling exceptions thrown in a separate thread?

查看:192
本文介绍了处理在单独线程中抛出异常的最佳方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个J2ME项目,为许多任务产生工作线程,例如下载HTTP内容。基本的线程布局与大多数java应用程序相似 - 主要的UI线程和工作线程在后台进行生成。我的问题是处理工作线程中发生的异常的最好方法是什么?

I am working on a J2ME project that spawns worker threads for numerous tasks such as downloading HTTP content. The basic thread layout is similar to most java apps--there is a main UI thread and worker threads spawned to do stuff behind the scenes. My question is what is the best way to handle exceptions that occur in the worker threads?

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

I usually adhere to the design rationale that most exceptions should be percolate as far as possible. When I write single threaded apps, it is common for me to percolate the exceptions all the way up to the UI layer and then report them in an error dialog to the user. Is there a similar practice for multithreaded apps? The most intuitive thing to me is to catch exceptions in the Thread.run() and then call an invokeLater on the UI thread to report it in a dialog. The issue I see here is that outside of the worker thread dying off prematurely, this approach does not really notify the UI thread there was an error. I do not see a clear way to throw an exception across threads so to speak.

谢谢,
Andy

Thanks, Andy

推荐答案

你不应该将UI代码插入你的工作人员!

You should NOT jam UI code into your workers!

/**
 * 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;
    }
}

这篇关于处理在单独线程中抛出异常的最佳方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆