Thread.stop: call-stack does unwind normally

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‘.

Advertisements

4 Responses to Thread.stop: call-stack does unwind normally

  1. Mark Amabile says:

    I have been running our application running Java 1.5_07 for a while now with this stop() logic. I have been tracking down a nasty bug where we need the Finally block to run in the thread.

    My understanding is… there is no guarantee it will run and / or complete the finally block when you issue the stop() method.

  2. pveentjer says:

    When a Thread.stop is called, a ThreadDeath error is thrown and it unwinds the stack normally and all the finally blocks are called. So you have the guarantee that the finally blocks are called.

  3. kasun says:

    Thanks for explaining deprecated thread.stop() in briefly. I think it is more better that if You can give the code that how to stop thread.

  4. Ivan Hrytsyuk says:

    We are facing the same problem as Mark Amabile.
    The magic is: finally blocks aren’t called from time to time.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: