【问题标题】:Java kills daemon threads in applet reloadsJava 在 applet 重新加载时杀死守护线程
【发布时间】:2011-04-20 09:25:49
【问题描述】:

我知道当没有其他非守护线程处于活动状态时,所有守护线程都应该被杀死。 我正在开发从静态对象获取数据的小程序。这些静态对象正在守护线程中从远程服务器下载一些数据。多个小程序可以访问相同的数据,因此为每个小程序运行线程是没有意义的。 问题是当我重新加载页面时。小程序正在重新加载,它们在这些静态对象中注册,一切都会好起来的,只是 JVM 会杀死守护线程。

也许我一步一步解释:

  1. Applet 正在加载,它在提供数据的静态对象中注册。
  2. 静态对象启动守护线程。
  3. 页面重新加载。
  4. Applet 正在卸载(调用了 stop() 和 destroy())
  5. 正在创建新的小程序实例并在静态对象中注册。
  6. JVM 在守护线程中抛出 ThreadDeath 并且通信停止。

在我看来,步骤 6 应该在 4 之后和 5 之前。 我错过了什么吗?

我开发的解决方法是在静态对象中注册之前休眠一段时间,让 JVM 杀死守护进程,然后自动创建守护进程,但这只是一种解决方法。有更好的解决方案吗?

【问题讨论】:

    标签: java applet daemon


    【解决方案1】:

    您为什么不终止stop()destroy() 中的守护线程以使事情更清楚。

    【讨论】:

    • 因为可能有另一个小程序实例或其他对象在等待来自服务器的数据。问题在于守护进程被 JVM 杀死的那一刻,而不是为什么。
    【解决方案2】:

    我不鼓励在小程序之间共享后台线程,但如果您坚持,您可以执行以下操作:

    您可以通过覆盖 Thread.setDefaultUncaughtExceptionHandler 来捕获 ThreadDeath,以确保不会错过它。 然后,您可以从该处理程序重新启动一个新的守护线程来替换被杀死的线程。

    您应该确保不要在后台线程中的共享成员上使用同步,因为您的线程可以在同步块中间停止,如 Thread.stop 所述(Java 插件使用 Thread.stop 杀死你的线程)。

    请注意,如果您在 2 个不同的选项卡中打开了至少 2 个小程序,则重新加载一个不会使 JVM 杀死您的线程。 守护进程标志在小程序环境中似乎没有任何作用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多