Why doesn't Thread.stop work in situations where Thread.interrupt doesn't work?
The official Sun Oracle stance on Thread.stop()
is that it should not be used. Among other arguments, they write:
It should be noted that in all situations where a waiting thread doesn't respond to Thread.interrupt, it wouldn't respond to Thread.stop either.
But I do not understand that. If a thread is busy actively working on something (not just waiting 开发者_JAVA技巧or blocking on an external resource) and doesn't explicitly check the interrupt flag, wouldn't Thread.interrupt()
do nothing while Thread.stop()
will still work (throw ThreadDeath
)?
But I do not understand that. If a thread is busy actively working on something (not just waiting or blocking on an external resource) and doesn't explicitly check the interrupt flag, wouldn't Thread.interrupt() do nothing while Thread.stop() will still work (throw ThreadDeath)?
I think you misunderstand the quoted text. It refers to a thread that is waiting, not a thread that is running. Specifically, it is referring to cases like the following:
When the thread is blocked in an I/O call, low-level JVM implementation issues prevent it responding to either a
stop
or aninterrupt
.A thread that doesn't want to be stopped can catch
ThreadDeath
, and this is analogous to a thread that doesn't want to be interrupted simply ignoring the flag.
Thread.stop is not an issue about being good or bad coding with regard to being able to bail out threads. You should not use it unless as a very last resort. It is possible to do your code and expect Thread.stop() to occur but in that case interrupt() will possible do just as fine.
The issue that stop() won't work where interrupt() doesn't (i.e. blocked on some native stuff): both stop and ineterrupt would use the same native signals to carry the call.
On POSIX, if SIGUSR2
(for instance) doesn't help the native code to bail out, it won't help either of interrupt/stop.
You can think of interrupt vs stop like that: both may use OS signals. The OS signals may not be honored by the native code. However, if they are: stop() also puts a Throwable on the stack that will be propagated in the java code. On the contrary interrupt only sets a flag.
The throwable, however, may pop-up in virtually any statement, so some invariants may fail to be properly handled.
Possibly, it's partly fixable via Thread.uncaughtExceptionHandler by throwing away large states, rolling back transactions, etc... Again: not advisable.
The main reason, as far as I understand, is that the ThreadDeath exception may be thrown anywhere, whereas the interupt flag has to be checked explicitly.
Consider this code running in a thread:
public void sellItem(Store s) {
synchronized (s) {
if (s.itemsAvailable > 0) {
s.itemsAvailable--;
s.itemsSold++;
}
}
}
If a ThreadDeath is thrown after s.itemsAvailable--
, the Store object is left in an inconsistent state. On the other hand, this code is safe:
public void sellLoop(Store s) {
while (!Thread.interrupted())
sellItem(s);
}
Source: http://download.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#stop%28%29
They say that Thread.stop()
would not work because (I guess) the throwable can be caught and ignored.
if the JVM is too busy to interrupt the thread, it's also too busy to kill it.
精彩评论