Tuesday, July 1, 2008

Alternatives of stop, suspend, resume of a Thread


Did you go through the first part of the article which discussed - 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? ... You may like to go through the first part before proceeding with this part.

This part of the article tries to answer the following questions:-

  • 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()?
What should be done instead of using stop() method?

If stop() is deprecated and therefore suggested not to be used then how should a situation requiring the usage of stop() method should be handled? Good question... we can follow the recommended approach by Sun which requires to have a variable, which should either be volatile or the access to the variable should be synchronized. The thread will check this variable regularly and hence the thread may be stopped in an orderly fashion by setting an appropriate value to the variable which will communicate the thread that it should stop in an orderly way now.

For example:

Instead of having the stop() as

...
private Thread theCurrentThread;
...
public void run(){
theCurrentThread = Thread.currentThread();
...
...
}

public void stop(){
theCurrentThread.stop();
}

we can have a graceful and safe stop as

...
public void stop(){
theCurrentThread = null;
}

What'll happen if we use the above mentioned graceful stop alternative on a thread which is into an infinite loop? Read this article to understand that - Impact of assigning null to a running thread executing an infinite loop >>.

How can we stop a thread that waits for long periods maybe for I/O?

We can follow the same graceful stop technique discussed above in this case as well. We just need to call the interrupt() method of the thread after assigning null to the thread. For example, we may have the stop method as:-

...
public void stop(){

Thread t = theCurrentThread;
theCurrentThread = null;
t.interrupt();

}

Why do we need to have another reference to call interrupt() on? Why don't we call on the same thread reference 'theCurrentThread' in this case? Easy question, I know. But leaving for you to think ... just to ensure that you're still awake :-)

Ans yes, in this approach if any method catches this InterruptedException thrown from the stop() method, then that method should either have InterruptedException in its throws list OR it should re-interrupt itself by throwing calling the interrupt() method again otherwise the purpose of rasing the InterruptedException from the stop() method will go in vain.

What if Thread.interrupt doesn't affect a thread?

It's bizarre, but if the thread stops responding to Thread.interrupt() method then we need to some application specific tricks to overcome the situation. For example, if the thread is waiting on a Socket and stops responding to interrupt() method, then we may close the Socket which will cause the thread to return immediately.

Be sure that if a thread doesn't respond to interrupt() method, it will not respond to the stop() method either. So, don't be tempted to use stop() in such situations.

Why are Thread.suspend and Thread.resume deprecated?

suspend() and resume() methods are deprecated as it may cause a deadlock to happen. The reason for this is that the suspend() method doesn't release the acquired monitors and if a suspended thread has already acquired the monitor of a critical resource then an attempt to acquire the same resource in the thread which would resume the suspended target thread will cause a deadlock.

What should be done instead if using suspend() and resume()?

The same approach what we follow to have a graceful stop can be followed in this case as well. We'll simply have a variable which will signify the various states of the thread and the target thread will keep polling the value of the variable and if the value indicates a suspend state then the thread will wait by calling the Object.wait method and if a value indicating the resumed state will cause the target thread to be notified using Object.notify method.

What does the method Thread.destroy do?

public void destroy() - this method was originally designed to destroy a thread without any clean-up i.e., without releasing any of the acquired monitors, which may cause deadlocks. This method was never implemented and a call to this method throws
NoSuchMethodError always.



Share/Save/Bookmark


No comments: