当线程不抛出异常时会发生什么?

问题描述 投票:0回答:3

我注意到,在这个javadoc中,https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.UncaughtExceptionHandler.html UncaughtExceptionHandler 用于当异常发生但未被捕获时。但是,该线程会悄悄失败吗?我想是的,因为它是异步处理其业务的,但我正在调查与我们的一个流程相关的问题,并且很惊讶现在才意识到这一点,我的职业生涯已超过 10 年了。

java multithreading
3个回答
2
投票

线程会悄悄失败:)

十多年前,有人遇到过类似的问题。随着时间的推移,系统的性能开始下降。最终,我确定了原因:某个自定义线程池中的工作线程抛出异常,并且该工作线程被终止。因此,随着时间的推移,线程池中的活动线程数量开始减少,性能下降。

问题被隐藏在没有记录异常的事实中。

[编辑]

我上面的回答不正确。下面的示例对此进行了演示:

import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(){
            public void run(){
                throw new RuntimeException();
            }
        };
        t.start();
        TimeUnit.SECONDS.sleep(10);
        System.out.println("done");
    }
}

运行代码时,将显示以下输出:

Exception in thread "Thread-0" java.lang.RuntimeException
    at Main$1.run(Main.java:8)
done

因此异常已记录。


0
投票

根据@pveentjar的更新答案,我运行了以下代码:

import java.util.concurrent.TimeUnit;

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread() {

            public void run() {
                throw new RuntimeException("purposeful!");
            }
        };
        t.setUncaughtExceptionHandler((thread, throwable) -> System.out.println("uncaught: " + throwable.getMessage()));
        t.start();
        TimeUnit.SECONDS.sleep(10);
        System.out.println("done");
    }
}

,并确定 uncaughtExceptionHandler 似乎从使用它的线程中捕获了异常,允许开发人员用它做他们想做的事情,但这留下了一个问题,如果不是为了将系统从无声的失败? 输出:

uncaught: purposeful!
[a pause of approximately ten seconds]
done

0
投票

我终于弄清楚了我的具体问题的根源。这是由于错误处理不当,导致线程静静地失败:

public class Main {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread() {

            public void run() {
                try {
                    //do some stuff
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("done-worker thead");
                throw new RuntimeException("purposeful!");
            }
        };
        t.setUncaughtExceptionHandler(
                (thread, throwable) -> System.out.println("main thread; uncaugh exception from worker threadt: " + throwable.getMessage()));
        t.start();
        TimeUnit.SECONDS.sleep(10);
        System.out.println("done-main thead");
    }
}

在执行“某些操作”时,应用程序遇到了 OutOfMemoryError,严格来说,这并不是一个异常。将catch语句改为

catch(Throwable t)
,解决了。

© www.soinside.com 2019 - 2024. All rights reserved.