9

Occasionally we must forcibly stop a thread as a best effort before entirely shutting down the whole JVM. Usually Thread#stop is cited as a surefire, even if ham-handed and deprecated, way to unconditionally stop a thread. This is not so, however: all the rogue thread has to do to keep itself running is catch ThreadDeath or a superclass:

public static void main(String[] args) throws InterruptedException {
  final Thread t = new Thread() { public void run() {
    for (;;)
      try { Thread.sleep(Long.MAX_VALUE); }
      catch (Throwable t) {
        System.out.println(t.getClass().getSimpleName() + ". Still going on...");
      }
  }};
  t.start();
  Thread.sleep(200);
  t.interrupt();
  Thread.sleep(200);
  t.interrupt();
  Thread.sleep(200);
  t.stop();
  Thread.sleep(200);
  t.stop();
}

This will print

InterruptedException. Still going on...
InterruptedException. Still going on...
ThreadDeath. Still going on...
ThreadDeath. Still going on...

Is there anything else that I could do to really, really stop a thread without killing the whole JVM?

4

2 回答 2

6

不,没有内置的简单方法可以真正停止线程。

这种方法,destroy,是计划但没有实施的:

已弃用。此方法最初设计用于在不进行任何清理的情况下销毁此线程。它持有的任何监视器都将保持锁定状态。但是,该方法从未实施。如果要实现的话,它会像suspend()那样容易死锁。如果目标线程在关键系统资源被销毁时持有保护它的锁,则没有线程可以再次访问该资源。如果另一个线程曾经试图锁定这个资源,就会导致死锁。这种死锁通常表现为“冻结”进程。

线程不是为了那个。他们不提供安全保障。另一个线程也可以终止 JVM 本身 - 或产生其他有问题的线程。

有关详细信息,请参阅为什么不推荐使用 Thread.stop、Thread.suspend 和 Thread.resume。你可以在这里阅读为什么。

于 2013-06-22T14:22:11.757 回答
1

无法保证在 Java 中可以停止该线程。最有力的方法是 Thread.stop 但这是等待发生的意外。替代方法是使用 Thread.interrupt 并让线程检查标志,但这两者都依赖于正确编码的线程,并且在标志的情况下,定期检查它。

就个人而言,我会确保我没有赶上 ThreadDeath。停止是停止线程的一种不好的方法,但至少你应该得到一个通知,只要你没有捕捉到 ThreadDeath。

于 2013-06-22T14:22:03.067 回答