【问题标题】:Java - switching back to main thread?Java - 切换回主线程?
【发布时间】:2009-03-05 06:00:12
【问题描述】:

出现异常时如何从不同的线程切换回主线程。当子线程引发异常时,我希望将通知发送到主线程并从主线程执行一个方法。我该怎么做?

谢谢。

附加信息

我正在从我的主方法调用一个方法,并在经过一些计算和更改后在那里启动一个新线程

Thread thread = new Thread() {
    @Override
    public void run() {
        .....
    }
}
thread.start();

【问题讨论】:

    标签: java multithreading


    【解决方案1】:

    当子线程发生异常时,主线程要做什么?对于子线程中的任何错误,它必须等待

    你可以在子线程中建立一个UncaughtExceptionHandler,它可以引发一个主线程正在等待的事件。

    【讨论】:

    • 它不必等待。它可以定期轮询队列以查找错误事件,如果没有要处理的事件,则继续执行其他任务。
    • @eickson,是的,它不需要一直等待,但它会在某个时候等待。我想确保 OP 理解这必须是等待/通知,即 Thread.start 不会返回调用者可以使用的值。
    • 这个方法(和我的方法)实际上并没有在主线程上执行,它们仍然是用 Thread.currentThread == 发生异常的线程来完成的。不确定这对 OP 是否真的很重要。
    • @TofuBeer:你指的是哪种方法(我的)?正如我所说,异常处理程序应该引发主线程的事件。您描述的回调不会自行工作。
    • 我说过任何方法都行不通——包括我的!我指的是 UncaughtExceptionHandler 在子线程而不是主线程上执行。 AFAIK 没有办法回到主线程。
    【解决方案2】:

    正如 TofuBeer 所说,您需要提供更多上下文,但如果该上下文表明您是一个摇摆应用程序...

    SwingUtilities.invokeLater(Runnable r) 允许您回调 Swing 的主执行线程。

    } catch (final Exception e) {
        SwingUtilities.invokeLater(new Runnable(){
            public void run() {
               //do whatever you want with the exception
            }
        }); 
    }
    

    【讨论】:

    • 是的,如何进行回调很大程度上取决于程序运行的方式。
    【解决方案3】:

    如果您的子线程是在主线程中创建的,您可能会弹出异常并在主线程上处理它。

    您也可以进行某种回调。

    不过,我还没有亲自尝试过。

    【讨论】:

      【解决方案4】:

      在应用程序的某个类中实现接口http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Thread.UncaughtExceptionHandler.html,并让它处理线程及其产生的异常。

      查看文档了解更多详情。

      编辑:这可能不是您想要的 - 我相信该方法将由刚刚引发异常的线程调用。如果您希望在主线程(在其上下文中)上执行某些方法,则主线程将不得不以某种方式等待它。

      但是,如果您只想处理异常,那就是一种情况。认为最好的方法是在线程内的 try...catch 块中处理异常。

      【讨论】:

        【解决方案5】:

        可能对你有用。

        public class Main
        {
            public static void main(final String[] argv)
            {
                final Main main;
        
                main = new Main();
                main.go();
            }
        
            public void go()
            {
                final Runnable runner;
                final Thread   thread;
        
                runner = new Foo(this);
                thread = new Thread(runner);
                thread.start();
            }
        
            public void callback()
            {
                System.out.println("hi!");
            }
        }
        
        class Foo
            implements Runnable
        {
            private final Main main;
        
            Foo(final Main m)
            {
                main = m;
            }
        
            public void run()
            {
                // try catch and handle the exception - the callback is how you notify main
                main.callback();
            }
        }
        

        【讨论】:

        • 完全牛。类!=线程。您不会通知代码中的任何其他线程。
        • 正确,我确实向他询问了更多上下文的问题(但从未得到可用的答案)。上面的代码确实让你通知 Main 出了点问题。请注意,我说它可能对他有用 - 不能肯定地说,因为他想要的东西是不可能的(AFAIK)
        • 这个问题清楚地表明了在主线程上调用某些东西的愿望......而不是“主”类。这个代码示例没有做到这一点。
        猜你喜欢
        • 1970-01-01
        • 2019-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-23
        • 1970-01-01
        相关资源
        最近更新 更多