为什么Thread.stop不能在Thread.interrupt不起作用的情况下工作?
官方 太阳 Thread.stop()
上的Oracle立场是不应该使用它。 在其他论点中, 他们写道 :
应该注意的是,在等待线程不响应Thread.interrupt的所有情况下,它也不会响应Thread.stop。
但我不明白。 如果一个线程正在忙于处理某些事情(不只是在外部资源上等待或阻塞)并且没有明确地检查中断标志,那么当Thread.stop()
仍然有效时, Thread.interrupt()
不会做任何事情(抛出ThreadDeath
)?
但我不明白。 如果一个线程正在忙于处理某些事情(不只是在外部资源上等待或阻塞)并且没有明确地检查中断标志,那么当Thread.stop()仍然有效时,Thread.interrupt()不会做任何事情(抛出ThreadDeath)?
我想你误解了引用的文字。 它指的是正在等待的线程,而不是正在运行的线程。 具体来说,它指的是以下情况:
-
当线程在I / O调用中被阻塞时,低级JVM实现问题会阻止它响应
stop
或interrupt
。 -
一个不想被停止的线程可以捕获
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太忙而无法中断线程,那么它也太忙而无法杀死它。