1

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

我希望能够在需要时中止并终止进程,例如客户/时间要求,或者在单个迁移中发生一些死循环。

在这里,我们称 abort 是一种优雅的方式,通过设置一个布尔标志来终止线程,并且一旦每个循环将首先检查该标志,然后决定是否继续。这已经实施,没有任何问题。

但是,我在杀死线程时遇到了麻烦。我的同事建议我重写 finalize() 方法并尝试在其中杀死它。但是,我在网上发现这种方法无法销毁对象,建议由 GC 调用,而是由用户调用。

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

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

非常感谢您的帮助。

PS:和JMX有关,并不代表真的和JMX有关系,只是我希望这个杀戮命令来自JMX控制台客户端。

4

2 回答 2

2

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

  • 根据定义,活动线程(即已启动但尚未终止的线程)是可访问的,因此不会被垃圾收集。所以添加一个 finalize 方法不会有任何影响。

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

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

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

  • 我会尝试通过使用而不是自定义标志来解决这个Thread.interrupt()问题Thread.isInterrupted()。这样做的好处是,中断也会解除阻塞,比如Thread.sleep Object.wait某些 I/O 操作。

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

  • System.exit()如果这些方法失败了,我会考虑通过调用... 如果这是一个合理的做法来拔掉整个应用程序的插头。

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

其他需要考虑的可能性是:

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

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


我想你说你看到了这样的建议,大意是打电话是个坏主意System.gc()。这是个好建议。

于 2011-03-30T06:56:10.570 回答
0

finally当方法在任何情况下退出时,您应该执行您想要执行的某些任务。人们给出的最可取的例子是使用数据库连接。

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

JVM 负责销毁对象。

于 2011-03-30T06:53:29.433 回答