如何使用VisualVM或使用unix命令终止java线程?

时间:2012-07-23 10:39:02

标签: java multithreading

我使用的是Windows 7操作系统。我的应用程序中有大约6个线程。为了测试警报以检查线程的运行状况,我需要手动终止线程并检查警报是否正常工作。我们可以杀死一个线程,就像我们如何使用pid杀死进程一样?

8 个答案:

答案 0 :(得分:37)

Dan Woods记录了如何在此博客条目中杀死一个帖子...... https://web.archive.org/web/20160302023213/http://www.rhcedan.com/2010/06/22/killing-a-java-thread 他执行的步骤涉及使用调试器(JDB)并在线程的执行中注入异常。具体地说...

  1. 确保使用以下参数启动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上的连接。

  2. 识别违规行为:
  3. 杀死线程。在此示例中,ThreadName是“btpool0-0?”。启动java调试器(也随JDK发行版一起提供),并附加到正在运行的JVM ...

      

    [root @ host~] #jdb -attach 50100

  4. 获取正在运行的线程的列表 - 这也将为我们提供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 测试了这个,它工作正常。