为什么Thread.stop不能在Thread.interrupt不起作用的情况下工作?

官方 太阳 Thread.stop()上的Oracle立场是不应该使用它。 在其他论点中, 他们写道 :

应该注意的是,在等待线程不响应Thread.interrupt的所有情况下,它也不会响应Thread.stop。

但我不明白。 如果一个线程正在忙于处理某些事情(不只是在外部资源上等待或阻塞)并且没有明确地检查中断标志,那么当Thread.stop()仍然有效时, Thread.interrupt()不会做任何事情(抛出ThreadDeath )?

但我不明白。 如果一个线程正在忙于处理某些事情(不只是在外部资源上等待或阻塞)并且没有明确地检查中断标志,那么当Thread.stop()仍然有效时,Thread.interrupt()不会做任何事情(抛出ThreadDeath)?

我想你误解了引用的文字。 它指的是正在等待的线程,而不是正在运行的线程。 具体来说,它指的是以下情况:

  • 当线程在I / O调用中被阻塞时,低级JVM实现问题会阻止它响应stopinterrupt

  • 一个不想被停止的线程可以捕获ThreadDeath ,这类似于一个不想被中断而只是忽略该标志的线程。

Thread.stop不是关于能够挽救线程的好或坏编码的问题。 除非作为最后的手段,否则不应该使用它。 可以执行你的代码并期望发生Thread.stop(),但在这种情况下,interrupt()可以做得很好。

stop()在interrupt()没有的情况下不起作用的问题(即在某些原生内容上被阻塞):stop和ineterrupt都会使用相同的本机信号来进行调用。

在POSIX上,如果SIGUSR2 (例如)没有帮助本机代码挽救,它将无助于中断/停止。 您可以将中断与停止视为:两者都可以使用OS信号。 本机代码可能不支持OS信号。 但是,如果它们是:stop()也将Throwable放在将在java代码中传播的堆栈上。 相反,中断只设置一个标志。

但是,throwable几乎可以在任何语句中弹出,因此某些不变量可能无法正确处理。

可能,它可以通过丢弃大型状态,回滚事务等来通过Thread.uncaughtExceptionHandler进行部分修复……再次:不可取。

据我所知,主要原因是ThreadDeathexception可能被抛出任何地方,而interupt标志必须被明确检查。

考虑在线程中运行的代码:

 public void sellItem(Store s) { synchronized (s) { if (s.itemsAvailable > 0) { s.itemsAvailable--; s.itemsSold++; } } } 

如果在s.itemsAvailable--之后抛出ThreadDeath,则Store对象将处于不一致状态。 另一方面,这段代码是安全的:

 public void sellLoop(Store s) { while (!Thread.interrupted()) sellItem(s); } 

资料来源: http : //download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#stop%28%29

他们说Thread.stop()不起作用,因为(我猜)throwable可以被捕获并被忽略。

如果JVM太忙而无法中断线程,那么它也太忙而无法杀死它。