【问题标题】:Thread vanishes without a trace线程消失得无影无踪
【发布时间】:2011-08-09 18:59:10
【问题描述】:

我正在尝试调试一个问题。我们很少有线程处理来自 BoundedLinkedQueue 的数据。处理完一条记录后,当前线程执行Thread.currentThread().yield()

现在,有时会观察到其中一个线程消失了!我跟踪了日志,发现这样一个“消失”的线程一直工作到 yield 语句。之后,找不到该线程的任何痕迹 - 在该线程看到的最后一个日志附近也不会引发任何错误或异常。

任何人都可以为调试方向提供任何指示吗?产量的使用是否正确?产量是一个可靠的说法吗?这是因为我发现 this 文章建议避免使用 yield 语句?有没有人见过这样的情况?

编辑:在一些研究中,似乎 try/catch 可能会遗漏一些异常,这些异常会被放入 System.err 中,这在多线程环境中可能不明显。感谢@JVerstry 的指针,我为线程设置了 uncaughtexceptionhandler。构建和运行过程需要很长时间。一旦我有了具体的东西,会更新更多。 以下是一些关于 UncaughtExceptionHandler 的链接:

【问题讨论】:

  • 你在什么操作系统/架构上运行?使用产量的理由?
  • 不知道你的线程为什么会消失,但是 yiel 是一个静态方法,并且总是暂停当前线程。你应该使用Thread.yield()
  • 能否请您发布源代码的示例快照

标签: java multithreading concurrency yield


【解决方案1】:

当这种情况再次发生时,我们能够获得线程转储,并且似乎该线程只是永远阻塞了 JDBC 调用 - jdbc jar 中的一个错误。我们只是用最新版本替换了jar,似乎已经解决了。感谢大家的宝贵意见 - 让我学到了很多新东西。另外,现在设置查询超时以防止永远阻塞。

【讨论】:

    【解决方案2】:
    1. 屈服后会发生什么?线程会退出还是会尝试处理队列中的另一条数据?
    2. 您应该验证在 yield 之后调用的内容实际上是通过日志记录调用的。
    3. 你怎么知道线程已经退出?您是否通过查看堆栈跟踪(使用 Jstack)进行了验证?
    4. 最后你为什么要使用yield?我假设您的 BoundedLinkedQueue 允许线程以线程安全的方式检索数据,或者如果队列为空则阻塞。为什么不让 JVM 管理线程调度?

    【讨论】:

    • 1.线程处理另一条数据。 2. 记录 yield 后什么都没有(这种情况偶尔会发生,一些随机线程消失) 3. 即使使用最外面的 try/catch 语句,我也看不到堆栈跟踪。因此,我添加了 uncaughtexceptionhandler 希望现在就捕获它。 4. 很多人建议使用表现良好的线程使用yield。 JVM 管理调度,但通过 yield 我们建议调度器这可能是接管 cpu 的好时机。
    • @advantej 3. 你如何确定线程消失了? 4. 如果没有经验证据,我不会假设使用产量会产生更好的结果。 5. 有多少线程从队列中拉数据? 6. 你有没有考虑让 java.util.concurrent 包中的 ExecutorService 来管理你的线程?
    • 3.没有线程痕迹,也没有线程 4 完成任务的证据。这是一种遗留代码,与大约 100 名客户合作良好 - 一对夫妇发现了这个问题。 5.不超过15个线程。 6. 不。人们害怕接触遗留的工作代码:D
    【解决方案3】:

    正如您在链接的文章中指出的那样,产量并没有定义当前量子是否被中断。如果您在线程退出之前立即让步,调度程序可能会完成线程的量程,从而导致线程立即退出。

    【讨论】:

      【解决方案4】:

      产量不会使线程消失。您的线程可能会引发异常并且未被捕获。你实现了uncaught exception handler 吗?如果没有,那么我建议你这样做。它会解释你的问题(除非线程自然而然地结束并且你的代码没有做你认为应该做的事情)。

      【讨论】:

      • @JVerstry ...谢谢。似乎我们没有未捕获的异常处理程序。但是,有一个顶级 try-catch 块可以捕获 Exception 对象。不幸的是,这里什么都没有发现。
      • 如果您确定您的 try/catch 实现得很好,那么您的代码很可能没有按照您的想法执行。否则,我会尝试使用未捕获的异常处理程序。它很容易实现。如果您仍然没有发现任何东西,那么您确定错误在编码中。
      猜你喜欢
      • 1970-01-01
      • 2014-01-23
      • 1970-01-01
      • 2020-12-23
      • 2021-06-21
      • 1970-01-01
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多