Re: What is so bad aboud Thread.stop() ?
On 7/31/2013 9:36 AM, taqmcg@gmail.com wrote:
The use of Thread.stop() is strongly deprecated, but I'm a bit confused by the explanation given in the documentation: (e.g., http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html)
Because it is inherently unsafe. Stopping a thread causes
it to unlock all the monitors that it has locked. (The
monitors are unlocked as the ThreadDeath exception propagates
up the stack.) If any of the objects previously protected by
these monitors were in an inconsistent state, other threads
may now view these objects in an inconsistent state.
Such objects are said to be damaged. When threads operate on
damaged objects, arbitrary behavior can result. This behavior
may be subtle and difficult to detect, or it may be pronounced.
Unlike other unchecked exceptions, ThreadDeath kills threads silently;
thus, the user has no warning that his program may be corrupted.
The corruption can manifest itself at any time after the actual
damage occurs, even hours or days in the future.
As I understand this, the ThreadDeath exception is treated exactly as
any other exception -- finally blocks are honored, it can even be
caught -- that might be thrown unexpectedly. E.g., if we got an
OutOfMemoryError or we happen to explicitly throw a RuntimeException
we're going to see exactly the same behavior with monitors released
progressively as we go up the stack. It's certainly easy enough to
catch and rethrow the ThreadDeath in its run method if I really want
to log it and address the one difference.
So what is the big hullaballoo about? Is there something special
going on here with Thread.stop(), or is this just a specific instance
of the fact the we should be very careful whenever a thread has been
stopped by an unexpected exception?
Thread.stop() might be called at any time in the to-be-stopped
thread, and that might be an issue, but at least in principle the
thread that issues the stop could check the to-be-stopped thread and
only stop it at 'appropriate' points where appropriate is defined by
the user.
E.g., suppose I have some concern that a piece of code that I'm about
to run might have an infinite loop in it (say I'm testing somebody
else's regular expression parser with lots of different RE's), but
it's not going to allocate any external resources (e.g., files, DB
connections). I could set/clear a flag as I enter and leave the
suspect code. Could I safely monitor this thread in another thread.
After say 100 seconds if a given expression hasn't parsed can the
monitor thread invoke a Thread.stop() safely if my flag shows that
the RE thread is caught in the parser?
I think this part is the critical part
# If any of the objects previously protected by
# these monitors were in an inconsistent state, other threads
# may now view these objects in an inconsistent state.
There are cases where using it may result in problems.
There may also be cases where it will work fine. But that is
not sufficient to consider something "safe".
Go with the recommended approach of having the external
thread set a flag and the thread itself read it and close
down.
Arne