【问题标题】:Why java ThreadPoolExecutor kill thread when RuntimeException occurs?为什么 java ThreadPoolExecutor 在 RuntimeException 发生时杀死线程?
【发布时间】:2013-10-01 18:41:39
【问题描述】:

为什么调用execute方法时会在worker中重新抛出未处理的异常?结果,将在下次执行时创建新线程以最大化线程数

【问题讨论】:

  • 你能给我们举个例子吗? (请把它放在问题中
  • 随意打开代码自己看看
  • 请把代码的相关部分贴在这里。
  • 另一个不知道如何使用网站的高级用户(有五个金徽章)实例。
  • 它不会“杀死线程”。线程杀死自己,因为 Runnable 抛出了一个未捕获的异常。这不是一回事。

标签: java concurrency


【解决方案1】:

为什么 java ThreadPoolExecutor 在 RuntimeException 发生时会杀死线程?

我只能猜测ThreadPoolExecutor.execute(...) 有线程调用runnable.run() 直接 而没有将其包装在FutureTask 中的原因是这样您就不会产生@987654324 的开销@如果你不关心结果。

如果您的线程抛出RuntimeException,这可能是一种罕见的事情,并且没有将异常返回给调用者的机制,那么为什么要为包装类付费?所以最坏的情况是,线程被杀死,将被线程池回收并重新启动。

【讨论】:

  • 它不会在提交时杀死它。 Runnable for execute 方法未包装在 FutureTask 中
  • 我不明白@aauser。您的 task 将被终止,但线程将继续运行并执行线程池中的下一个作业,除非它已被关闭。
  • 当通过“execute”方法提交任务时,它不会通过 FutureTask 进行包装。如果任务是通过“提交”提交的,它会通过 FutureTask 包装并处理异常。可以做简单的测试,创建SingleThreadedExecutor,执行Runnable,记录threadId,抛出异常,执行另一个Runnable,比较ThreadId
  • 嗯。在@aauser 之前从未欣赏过这一点。谢谢。
【解决方案2】:

没有办法正确处理异常。异常不能传播到调用者线程,也不能简单吞下。

线程中抛出未处理的异常被委托给ThreadGroup.uncaughtException方法,该方法将输出打印到System.err.print,直到ThreadGroup覆盖所需的行为。

所以这是预期的行为,它可以与在 main 方法中抛出未经处理的异常进行比较。在这种情况下,JVM 会终止执行并将异常打印到输出。

但我不确定,为什么ThreadPoolExecutor 不自己处理,ThreadPoolExecutor 可以自己记录。创建新的Thread 并不便宜。

也许有一个假设,与Thread 关联的一些资源(本机、threadLocal、threadStack 等)应该被释放。

【讨论】:

    猜你喜欢
    • 2019-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 2011-05-08
    相关资源
    最近更新 更多