线程消失得无影无踪



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

现在,偶尔可以观察到其中一个线程消失了!我跟踪了日志,发现这样一个"消失"的线程一直工作到yield语句。在此之后,不会发现该线程的任何踪迹-也不会在该线程的最后一个日志附近抛出任何错误或异常。

谁能给点调试方向的指点?yield的用法正确吗?收益率是一个可靠的陈述吗?这是因为我发现这篇文章建议避免yield语句?有人见过这种情况吗?

编辑:在一些研究中,似乎try/catch可能会错过一些例外,而这些例外会被放入系统中。在多线程环境中可能不明显的错误。感谢@JVerstry的指针,我已经为线程设置了uncaughtexceptionhandler。构建和运行过程需要很长时间。一旦有了具体消息,我会及时更新。这里有几个关于UncaughtExceptionHandler的链接:

  • 线程。UncaughtExceptionHandler
  • 在JDK 1.5中捕获未捕获的异常
  • Java理论与实践:嘿,我的线程去哪里了?
  • 了解JVM系列1 -未捕获异常处理程序

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

Yield不会使线程消失。你的线程可能会抛出一个异常而没有被捕获。您是否实现了未捕获的异常处理程序?如果没有,那么我建议你这样做。它会解释你的问题(除非线程自然结束,你的代码没有做你认为它应该做的事情)。

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

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

最新更新