在java中杀死一个对象

时间:2011-03-30 05:42:42

标签: java jmx destroy

我目前正在使用JMX来管理和监控在Java类中执行的大型迁移过程。

我希望能够在我需要的时候中止并杀死这个过程,例如需要客户/时间,或者在一次迁移中发生一些死循环。

在这里,我们通过设置一个布尔标志来优先调用abort来杀死一个线程,并且每个循环首先检查该标志,然后决定是否继续。这已经实施,没有任何问题。

然而,我遇到了杀死线程的麻烦。我的同事建议我覆盖finalize()方法并尝试在其中删除它。但是,我在网上找到的是这种方法无法破坏对象,建议由GC调用,而不是用户调用。

我想这个理论是可以的,只要对象被破坏,就不会有更多的过程发生。我不确定这是否能够在JAVA中实现。

另外,我想知道,你们还有其他方法可以给我一些提示。

非常感谢你的帮助。

P.S:与JMX有关,并不意味着它与JMX有关,只是我希望这个kill命令来自JMX控制台客户端。

2 个答案:

答案 0 :(得分:2)

要理解你在说什么有点难,但我不认为finalize会有任何帮助。

  • 根据定义,可以访问活动线程(即已启动但尚未终止的线程),因此不会进行垃圾回收。因此,为其添加finalize方法不会产生任何影响。

  • 如果你所谈论的对象不是线程,添加finalize可能也无济于事:

    • 如果线程的runnable(或其他)有对该对象的引用,那将阻止它被垃圾回收。
    • 如果没有,并且对象确实无法访问,则在GC决定收集对象之后,finalize方法才会运行......这可能永远不会发生。
    • 即使调用了finalize方法,它还能做什么?你已经告诉要关闭的线程......并且什么都没发生。

这里真正的问题似乎是线程没有响应你的“正常关闭”标志。

  • 我尝试使用Thread.interrupt()Thread.isInterrupted()而不是自定义标记来解决此问题。这样做的好处是,中断还可以解除对Thread.sleep Object.wait和某些I / O操作等内容的阻止。

  • 如果线程被阻止尝试通过套接字或管道与某些外部服务进行通信,则可以通过关闭套接字和/或流来解除阻塞。这当然假设您的关闭代码可以获得对Socket或Stream对象的引用。

  • 如果这些方法失败了,我会考虑通过调用System.exit()来取消整个应用程序的插件......如果这是合理的事情。

  • 如果您完全绝望(并且有点疯狂),您可以考虑使用已弃用的Thread.abort()方法。但是有一种可能性会使整个应用程序处于破碎和无响应的状态。所以我会推荐这种方法。

要考虑的其他可能性是:

  • 线程实际上已响应并退出,但您的关机代码没有注意到,
  • 线程在您尝试将其关闭之前就已经死了,并且您的关闭代码没有注意到,
  • 线程已死锁,或
  • 需要修改runnable中有一些长时间运行(但不是无限)的循环,以便更频繁地检查“你现在死”标志。

您可以通过附加调试器并进行线程转储来诊断其中一些事项。


我想你说你看到了一个建议,即调用System.gc()是一个不好的想法。这是一个很好的建议。

答案 1 :(得分:0)

当方法在任何条件下退出时,您应该在finally中执行您要执行的特定任务。人们给出的最好的例子就是提出数据库连接。

是的,建议在JVM上留下垃圾收集。

JVM负责对象的删除。