分析多线程Java应用程序

Phi*_*ppe 5 java multithreading

在我参与的开源应用程序中,我们遇到了一个错误,应用程序并不总是正常关闭.这就是我想要解决的问题.

经验表明,这种情况大部分发生在线程和进程启动时,但未正确管理(例如,线程正在等待套接字连接,应用程序正在关闭并且线程一直在等待).
考虑到这一点,我在整个源代码中搜索了'.start()',发现了53次(让我感到有些害怕).
作为第一步,我想创建一个帮助器类(ThreadExecutor),其中当前代码'thread.start()'将被'ThreadExecutor.Execute(thread)'替换为a)现有源中只有一些更改和b)一个单独的类,我可以很容易地检查哪些线程没有按预期结束.要做到这一点,我想

  • 在调用Execute方法时,将要执行的线程添加到名为activeThreads的列表中
  • 启动线程
  • 结束时将其从activeThreads列表中删除.

这样我就可以获得所有正在执行的线程的最新列表,当应用程序挂起时,我可以看到哪个线程正在导致它.

问题:

  • 你对这个概念有什么看法?我通常编写c#并知道我是如何使用.NET与worker一起工作的,但我不太确定Java中哪些是最好的(我想在现有源代码中修改尽可能少的代码行).
  • 如果概念似乎没问题,我怎样才能得到线程终止的通知.我想避免额外的线程每隔一段时间检查一次activeThreads中包含的所有线程的状态,如果它们终止则删除它们.

只是为了澄清:在弄清楚如何正确终止应用程序之前,我在这里要问的是找到哪些线程对于某些非常难以重现的测试用例的原因是什么是最好/最简单的方法.

Pau*_*rie 6

在更改任何代码之前,我会尝试分析您的应用程序的行为.代码更改可能会引入新问题 - 如果您尝试解决问题,则不会出现您想要执行的操作.

关于当前运行的线程,内省应用程序状态的最简单方法是获取线程转储.你说你的问题是应用程序在关机时挂起.这是应用线程转储的完美方案.您将能够看到哪些线程被阻止.

您可以在此处阅读有关线程转储的更多信息.


Pet*_*hev 2

尝试使所有线程成为守护进程(当所有剩余线程都是守护进程时终止JVM)。在启动每个线程之前使用thread.setDaemon(true) 。

  • 这听起来相当于向你的应用程序射击,所以它肯定会死掉。 (2认同)