Abstract
The Thread.stop method is deprecated and calling this method could lead to problems. However, it appears that my understanding of the stop mechanism was incorrect; the stopping thread unwinds the call-stack normally, instead of stopping on the spot.
Introduction
I’m preparing a presentation about low level concurrency issues, like monitor-locks and the wait/notify mechanism. I’m going to give this presentation on November 28 at Xebia: the company I work for.
One of the the issues I’m going to discuss is the Thread.stop method and why it is deprecated. But after refreshing my memory, by (re)reading the documentation, I gained a renewed insight about this matter and although it doesn’t change anything about the fact that the stop methods shouldn’t be used, I find it interesting enough to blog about. This also helps me to make sure, I won’t forget it.
Old (and incorrect) understanding
My old understanding was this: when a thread sees that the Thread.stop method was called, it stops processing other instructions and dies. The problem with this stopping mechanism, is that a thread has no chance to do clean-ups like:
- executing finally blocks or exception handlers
- releasing monitor-locks: the locks are obtained when entering a synchronized statement (or method). Normally these are transparently released, when the thread exits the critical section.
Example with not executed finally block:
Connection con = connectionPool.take();
try{
..while executing this part, the thread is stopped.
}finally{
connectionPool.return(con);
}
In this example the connection is not returned to the pool because the finally block is not run.
Example with a synchronized block:
synchronized(someobject){
..while executing this part, the thread is stopped
}
In this example the lock is not returned, because the release of that lock, when the thread exits the synchronized block, is not executed. I thought the lack of releasing locks, and other resources, caused by the abrupt termination of the thread, is the reason why the stop method is deprecated.
Renewed understanding
But I realized this understanding wasn’t correct, after reading the following document ‘Why Are Thread.stop, Thread.suspend,
Thread.resume and Runtime.runFinalizersOnExit Deprecated?‘. The first thing that was different from what I expected, was that all monitor-locks are released when a thread is stopped. How is this realized? Is a special end-of-life task being executed by the Java virtual machine, or operating system, when a thread is stopped?
Luckily the Thread.stop method doesn’t rely on a special mechanism to release those locks; it uses the normal exception mechanism to unwind the call-stack. When the stop method is called, the receiving thread will throw a ThreadDead error, regardless of what is was doing. As soon as this exception (technically it’s an Error) is thrown, the thread is able to unwind the call stack; giving all finally blocks and exception handlers chance to execute. The ThreadDead exception normally is not caught (and possibly discarded), because it is an java.lang.Error. This allows a thread to unwind the call-stack completely, so it can die. This means that all resources can be returned; monitor-locks are released and database connections are returned the connection pool.
Why is Thread.stop deprecated
The reason why the Thread.stop method is deprecated, is that all monitor-locks are released when the call-stack is unwound. This leaves the objects, protected by these monitor-locks, probably in an inconsistent state. This means that other threads can access these damaged objects. Preventing this problematic behavior is simple: don’t use the Thread.stop method. If you want to know how to stop a thread, I recommend reading the section ‘What should I use instead of Thread.stop?’ in the earlier provided document or reading ‘Java Concurrency in Practice‘.
Posted by pveentjer
Posted by pveentjer
Posted by pveentjer