我正在使用 Windows 7 操作系统。我的应用程序中有6
线程。为了测试警报以检查线程的健康状况,我需要手动终止线程并检查警报是否正常工作。我们可以像杀死一个进程一样杀死一个线程pid
吗?
8 回答
Dan Woods 在此博客条目中记录了如何杀死线程... https://web.archive.org/web/20160302023213/http://www.rhcedan.com/2010/06/22/killing-a-java -thread 他执行的步骤涉及使用调试器 (JDB) 并在线程执行中注入异常。具体来说...
确保使用以下参数启动您的 java 程序:
-Dcom.sun.management.jmxremote.port=50199
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
-Xrunjdwp:transport=dt_socket,address=50100,server=y ,暂停=n这将允许我们在确定是哪个线程导致问题后,将 java 调试器附加到正在运行的进程。此外,请确保您正确设置了 iptables,以便仅允许来自您管理的主机/工作站的 50100 和 50199 连接。
- 识别有问题的线程:
杀死线程。在此示例中,ThreadName 为“btpool0-0?”。启动 java 调试器(也随 JDK 发行版一起提供),并附加到正在运行的 JVM……</p>
[root@host ~]# jdb -attach 50100
获取一个正在运行的线程列表——这也会给我们 JVM 看到的线程 id:
> threads
--snip--
(org.mortbay.thread.BoundedThreadPool$PoolThread)0x25cb
btpool0-0 running
--snip--
我们要杀死的线程 id 是“0x25cb”。杀死线程的第一步是跳进去,然后挂起……</p>
thread 0x25cb
btpool0-0[1] suspend 0x25cb
btpool0-0[1] step
Step completed: <... snip ...>
btpool0-0[1] kill 0x25cb new java.lang.Exception()
killing thread: btpool0-0
btpool0-0[1] instance of
com.site.package.name(name='btpool0-0', id=9675) killed btpool0-0[1]
退出java调试器,你就完成了!
没有安全的方法来“杀死”一个线程而不杀死它所在的进程。这不是你会故意做的事情。出于测试目的,我会在您的应用程序中添加代码来支持这一点。
这不是真的。如果您知道线程 ID,您始终可以使用 GDB 附加到 JVM 进程并调用 pthread_kill。您只需要从 java 线程转储(执行 kill -3)进行翻译,它会为您提供一个十六进制 id(本机 id),然后查看 GDB 中的线程列表(信息线程)并找到真正的线程 id。
这被证明是有效的。
正如彼得所说,你不能安全地做到这一点。确实在某些平台Thread.kill
上甚至没有实现。然而:
如果这只是为了测试,那么调用的单元测试
Thread.kill
是合理的……假设它在需要工作的测试平台上工作。(源代码中的“大声”注释是为了帮助人们移植单元测试......)另一种选择是向可运行线程添加一些代码,允许您的单元测试告诉它死亡。如果线程代码需要(几乎)是生产代码才能工作,您可以创建一个覆盖某些内容的子类,以便它以适合您目的的方式“中断”......用于测试。事实上,这种方法允许您以受控方式“中断”线程,从而可能允许您测试警报代码的不同方面。
您不能从外部(操作系统或调试器)执行此操作,您必须编写自己的线程看门狗,它可以与用户交互并杀死您想要的线程。
尝试在这里查看如何使用 java 处理信号
在线程中等待一段时间并在代码中终止线程 - 简单的方法。
在java中你不能杀死喜欢的unix。您可以interrupt
在 java 中执行,也可以在 unix 中终止进程。
正如之前buzz3791的帖子中所提到的,它使用jdb 工作。然而我注意到的变化是,你不能杀死线程,但你可以中断或挂起线程。
#jdb -附加 50100
线程——这将显示在组和引用处理程序部分下的 jvm 上运行的所有线程。
团体 | 引用处理程序 |
---|---|
:(com.orienttechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary)0x36c1: | OrientDB (/xxx.xxx.xxx.xxx:123) <- BinaryClient (/xxx.xxx.xxx.xxx:678) |
线程 0x36c1——这将是线程 ID,可以从您希望杀死/中断的线程中的一个线程中选取并运行此中断 0x36c1
OrientDB (/xxx.xxx.xxx.xxx:123) <- BinaryClient (/xxx.xxx.xxx.xxx:678)[1]中断 0x36c1
您可以多次尝试相同的中断命令,如果已经中断,则会显示线程 id 无效。因此您知道线程已被杀死,这可以通过查看堆栈跟踪来验证并确认。
使用 jdk 8 在 OrientDB 数据库服务器上对此进行了测试,并且可以正常工作。