Tuesday, July 1, 2008

Why stop, suspend, & resume of Thread are Deprecated

This is a slightly longer article and hence divided into two parts. This is the first part of the article, which will try to answer the following questions:-

  • Why Thread.stop() method is deprecated in Java?
  • Why ThreadDeath is a subclass of Error and not of Exception?
  • Can't we catch the ThreadDeath and fix the damaged objects?
  • What will happen if stop() method is called on a thread which is yet to start?
Why Thread.stop() has been deprecated?

Thread.stop() - public final void stop() - This method is deprecated for the simple reason that it's unsafe and may lead the program to some unexpected circumstances. Thread.stop() when called, it causes the thread to release all the acquired monitors and throw a ThreadDeath error, which ultimately causes the thread to die. Since, the thread releases all the acquired monitors immediately, so it may leave few objects (whose monitors were acquired by the thread) in an inconsistent state. Such objects are called damaged objects and obviously they may result into some arbitrary behavior.

In case a Security Manager is installed, the this method causes the checkAccess method to be called first which may result into a SecurityException and this exception will of course be raised in the calling thread. If the stop() method is being used to stop a different thread (than the calling thread) then the Security Manager's checkPermission method will also be called in addition to the checkAccess method. Both of these methods may result into a SecurityException to be thrown in the calling thread.

Can't the ThreadDeath object be caught and all the damaged objects be fixed?

Thoretically yes, but practically NOT possible as a thread may throw this ThreadDeath error almost anywhere and what if a ThreadDeath is thrown while executing the catch or finally block of the first ThreadDeath which we just caught... and so on. Don't you think that it may soon become practically infeasible to guarantee a fixed version of all the damaged objects? This is why the designers of Java preferred to deprecate the method than to ask the developers to do such a complex and almost infeasible work to ensure damage-control in all the cases while using stop method.

Why did they have it in the first place and why didn't they remove it altogether?

Maybe because we may face scenarios (of course not frequently, but only very rarely) where the side effect of stop() method (or any other deprecated method for that matter) may become insignificant than the actual affect which the method can do. So, designers can't simply remove the method to maintain the completeness of the language - they either need to design an equivalent method free from all the side-effects OR to allow the developers to use if they badly need it. Marking such methods as deprecated simply serves the purpose of discouraging the developers for using those methods and noe they will use them only if they are left with no other possible workaround.

Why Thread.stop(Throwable) has been deprecated?

Thread.stop(Throwable) - public final void stop(Throwable obj) - this variant of the stop method causes the thread to complete abnormally and to throw the passed parameter of type Throwable as an exception. This abnormal completion of the thread makes this method unsafe and potentially dangerous for the same reasons as discussed in the other variant of the stop() method and hence it's deprecated. In addition this variant may require a checked exception to be thrown which the target thread may not be prepared to handle and throw. This may lead to a very awkward situation and a defined behavior is probably not guaranteed in such a case.

A null value passed as the parameter will expectedly result into a NullPointerException in the calling thread. In case a Security Manager is installed, this variant may also throw SecurityException the same way as the other variant may.

What will happen if we call stop() method on a thread which is not yet started?

Interesting question, isn't it? Well... We're allowed to call stop() method (both the variants) on a thread which is yet to be started. In such a case, if the thread starts then the stop() method causes it to die immediately.

Why are they allowed then? Okay... how can we handle it otherwise? At compile time we can't check if the thread is started or not and at run time the stop() (with zero arguments) method call requires a ThreadDeath object to be thrown, so how will this requirement be met if we don't wait for the thread to eventually start and then be terminated by throwing ThreadDeath? Maybe we can create, start and terminate a dummy thread immediately when such a call is encountered. But, what will we gain by doing this? In fact that will be the same as the worst possible scenario where all such threads (un-started threads) actually get
started and terminated. In all possibilities, we may even have few such threads which don't start for the entire life cycle of the application. So why to waste time doing something in advance which will ultimately be done if required. Similar explanation can be given for the other variant of the stop() method because that also requires the target thread to complete abnormally - in addition that requires the passed Throwable type object to be thrown. Even worse situation to handle in advance, what do you say?

What's ThreadDeath? Why is ThreadDeath a subclass of Error and not of Exception?

public class ThreadDeath extends Error - an object of this class is thrown when the Thread.stop() method is called without any argument. If a method catches this thrown object then it should rethrow the error so that the thread actually dies. This is the reason why the ThreadDeath class has been made a subclass of the Error class and not of the Exception class. Many applications simply use Exception type to capture all the exceptions and handle them either by simply ignoring OR maybe by doing something in the handler. The ThareadDeath when thrown should not be handled that way. It's thrown only when Thread.stop() method is called and that simply expects the thread to die and not to be handled some other way.

The second part of the article answers the subsequent questions to complete the article. These questions are:-
  • What should we do instead of using stop() method?
  • How can we stop a long waiting (maybe due to I/O) thread?
  • What if a thread doesn't respond to Thread.interrupt() call?
  • Why are Thread.suspend & Thread.resume deprecated?
  • What should be done instead of using suspend & resume?
  • What's Thread.destroy()?
Read Next - part two of the article - alternatives of stop, suspend, resume in Java >>

Liked the article? You may like to Subscribe to this blog for regular updates. You may also like to follow the blog to manage the bookmark easily and to tell the world that you enjoy GeekExplains. You can find the 'Followers' widget in the rightmost sidebar.


No comments: