我使用的是Windows 7操作系统。我的应用程序中有大约6
个线程。为了测试警报以检查线程的运行状况,我需要手动终止线程并检查警报是否正常工作。我们可以杀死一个线程,就像我们如何使用pid
杀死进程一样?
答案 0 :(得分:37)
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 =假
-Dcom.sun.management.jmxremote.ssl =假
-Xrunjdwp:运输= dt_socket,地址= 50100,服务器= Y,暂停= N
这将允许我们将java调试器附加到正在运行的进程之后 我们确定哪个线程导致了问题。另外,请确保 你有适当的iptables设置,以便只允许 来自您管理的主机/工作站的50100和50199上的连接。
杀死线程。在此示例中,ThreadName是“btpool0-0?”。启动java调试器(也随JDK发行版一起提供),并附加到正在运行的JVM ...
[root @ host~] #jdb -attach 50100
获取正在运行的线程的列表 - 这也将为我们提供JVM看到的线程ID:
> threads
--snip--
(org.mortbay.thread.BoundedThreadPool$PoolThread)0x25cb
btpool0-0 running
--snip--
我们要杀死的线程ID是“0x25cb”。杀死线程的第一步是跳入它,并暂停它......
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调试器,你就完成了!
答案 1 :(得分:15)
没有安全的方法来“杀死”一个线程而不会杀死它所处的进程。这不是你故意做的事情。出于测试目的,我会在您的应用程序中添加代码以支持此功能。
答案 2 :(得分:6)
事实并非如此。您始终可以使用GDB附加到JVM进程,并在知道线程ID时调用pthread_kill。你只需要从java线程转换(做一个kill -3)转换,它给你一个十六进制id,(本机id),然后查看GDB中的线程列表(信息线程)并找到真正的线程id。
事实证明这是有效的。
答案 3 :(得分:4)
彼得说,你不能安全地做到这一点。实际上,在某些平台上Thread.kill
甚至没有实现。但是:
如果这是只是进行测试,那么调用Thread.kill
的单元测试将是合理的......假设它在需要工作的测试平台上工作。 (源代码中的“响亮”评论是为了帮助人们移植单元测试......)
另一种方法是向线程runnable添加一些代码,允许你的单元测试告诉它死掉。如果线程代码需要(几乎)生产代码才能使用,你可以创建一个子类来覆盖某些东西,以便它以适合你的目的“破坏”...进行测试。实际上,这种方法允许您以受控方式使线程“中断”,从而可能允许您测试警报代码的不同方面。
答案 4 :(得分:2)
你无法从外部(操作系统或调试器)进行操作,你必须编写自己的线程看门狗,它可以与用户交互并杀死你想要的线程。
尝试查看here如何使用java
处理信号答案 5 :(得分:0)
在java中,你不能杀掉像unix这样的东西。您可以interrupt
使用java进行操作,也可以在unix中终止进程。
答案 6 :(得分:0)
在线程中等待一段时间并在代码中杀死线程 - 简单方法。
答案 7 :(得分:0)
正如 buzz3791 在上一篇博文中提到的,它使用 jdb 工作。但是我注意到的变化是,您不能杀死线程,但可以中断或挂起线程。
#jdb -attach 50100
<块引用>threads -- 这将显示在组和引用处理程序部分下的 jvm 上运行的所有线程。
组 | 引用处理程序 |
---|---|
:(com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary)0x36c1: | OrientDB (/xxx.xxx.xxx.xxx:123) <- BinaryClient (/xxx.xxx.xxx.xxx:678) |
thread 0x36c1-- 这将是可以从您希望杀死/中断的线程中的一个线程中选取的线程 ID 并运行此 interrupt 0x36c1
OrientDB (/xxx.xxx.xxx.xxx:123) <- BinaryClient (/xxx.xxx.xxx.xxx:678)[1] interrupt 0x36c1
同一个中断命令可以多次尝试,如果已经中断了,会显示线程id无效。这样你就知道线程被杀死了,这可以通过查看堆栈跟踪来验证并确认。
在 OrientDB 数据库服务器上用 jdk 8 测试了这个,它工作正常。