And you thought you knew Java Multithreading

You think you can “Stop” a “Thread”

In Java, there is no way to quickly and reliably stop a thread.
Once you start a thread, nothing can (safely) stop it, except the thread itself. At most, the thread could be simply asked – or interrupted – to stop itself.

Hence in Java, stopping threads is a two step procedure:

  • Sending stop signal to thread – aka interrupting it
  • Designing threads to act on interruption

Interrupting a Thread

If any thread is in sleeping or waiting state (i.e. sleep() or wait() is invoked), calling the interrupt() method on the thread, breaks out the sleeping or waiting state throwing InterruptedException. If the thread is not in the sleeping or waiting state, calling the interrupt() method performs normal behaviour and doesn’t interrupt the thread but sets the interrupt flag to true. Let’s first see the methods provided by the Thread class for thread interruption.

  • public void interrupt()

A thread in Java could be interrupted by calling `Thread.interrupt()` method.
an interrupt() will either throw an InterruptedException (if the thread is executing a method which permits this, like sleep() or wait()), or it sets the isInterrupted() status of the thread – but not both. (If you catch an InterruptedException, you’re supposed to be able to figure out that this means the thread was interrupted, without needing to check the isInterrupted() method.)

  • Designing threads to act on interruption
  • public static boolean interrupted()

The interrupted() is a static method in Thread class that determines if the current thread has been interrupted. “The interrupted status of the thread is cleared by this method”. Therefore, if a thread was interrupted, calling interrupted() once would return true, while a second call to it would return false until the current thread is interrupted again.

  • public boolean isInterrupted()

The isInterrupted() is an instance method that tests if this thread instance has been interrupted. “The interrupted status of the thread is unaffected by this method”.

isInterrupted() method returns true if the internal interrupted flag is set for the thread, or false otherwise.
When you want to interrupt a thread, you need to have a reference to it, ie, a variable that holds a reference to the thread you want to interrupt. Say I have a variable myThread of type Thread, that contains a reference to the thread I want to interrupt. I can now interrupt that thread by calling
myThread.interrupt();
What does this do to the called thread? Like I mentioned above, this sets the internal interrupted flag for the thread. Now if I have code in the myThread Thread that calls isInterrupted(), it will return true.
the other method, interrupted() is similar to isInterrupted() in that it returns the true/false status of the interrupted flag, EXCEPT it also clears the flag, so if you call interrupted() and it returns true, the very next time you call interrupted() it will return false, untill your thread is again interrupted. This method is useful when you are going to be interrupted a lot and you want to make sure you only handle each interruption one time, with a specific method for example.

When an InterruptException is thrown, the interrupt is considered to be handled and the interrupted flag is cleared.
The Thread.interrupted() static method is used in code that should be interruptable but does not normally wait() or sleep() – for instance, I/O or a lengthy calculation. For instance, you could use :

...
if (Thread.interrupted()) {
   throw new InterruptException();
}
...

at a suitable point in your loop, and handle the exception in the usual way. The interrupted() method, too, clears the interrupt flag because the interrupt is considered to be handled.
Finally, there is the Thread.isInterrupted() instance method. This is primarily a way for other threads to see if the thread has an unhandled interrupt, but it can also be used by a thread to look at its own interrupted status without clearing the flag (Thread.currentThread().isInterrupted()).

Usefulness of the Thread.interrupted() method :

I think you have a problem with it because it checks the current thread to see if it is interrupted. I guess you think there is a problem with that because if the Thread is interrupted how could it be executing to the point where it would be able to check if it was interrupted?

This all comes down to understanding what ‘interrupting’ a Thread is. Interrupting a Thread isn’t causing it to stop execution, and it doesn’t necessarily mean it throws an exception either. If you read the JavaDocs for Thread#interrupt() you will see that, except for a few specific situations, all that method does is set a status flag. You should think of it as a ‘request to interrupt’. Your job, as a Thread-savvy programmer is to react to those requests when appropriate, and to respond to the interruption requests is to periodically check on the interrupted status of the Thread you are running in. There are two ways to do it – First you could get a reference to the current thread and check the isInterrupted() flag, and second you could call the static Thread.interrupted() method (as Muhammad said there is a difference in how the two methods function). Once you detect that an interrupt has been requested you can then react to it in a clean and orderly way.

As the JavaDocs state, certain code, like wait() and Thread.sleep() will check the interrupted status flag and react by throwing an exception, others will react in other ways. But if you have code that runs in its own Thread and has a continuous or long lived loop then it is often a good idea to make sure your code reacts to the interruption itself.

Example :

public static void main(String[] args) throws Exception {

        /**
         * A Thread which is responsive to Interruption.
         */
        class ResponsiveToInterruption extends Thread {
            @Override public void run() {
                while (!Thread.currentThread().isInterrupted()) {
                    System.out.println("[Interruption Responsive Thread] Alive");
                }
                System.out.println("[Interruption Responsive Thread] bye**");

            }
        }

        /**
         * Thread that is oblivious to Interruption. It does not even check it's
         * interruption status and doesn't even know it was interrupted.
         */
        class ObliviousToInterruption extends Thread {
            @Override public void run() {
                while (true) {
                    System.out.println("[Interruption Oblivious Thread] Alive");
                   // Restore the interrupted status
                   //Thread.currentThread().interrupt();
                }
                // The statement below will never be reached.
                //System.out.println("[Interruption Oblivious Thread] bye");
            }
        }

        Thread theGood = new ResponsiveToInterruption();
        Thread theUgly = new ObliviousToInterruption();

        theGood.start();
        theUgly.start();

        theGood.interrupt(); // The thread will stop itself
        theUgly.interrupt(); // Will do nothing
}

<strong>O/P :</strong>
[Interruption Oblivious Thread] Alive
[Interruption Responsive Thread] Alive
[Interruption Responsive Thread] Alive
[Interruption Oblivious Thread] Alive
[Interruption Responsive Thread] bye**
[Interruption Oblivious Thread] Alive
[Interruption Oblivious Thread] Alive
[Interruption Oblivious Thread] Alive
[Interruption Oblivious Thread] Alive
....

Dealing with InterruptedException
If throwing InterruptedException means that a method is a blocking method, then calling a blocking method means that your method is a blocking method too, and you should have a strategy for dealing with InterruptedException. Often the easiest strategy is to throw InterruptedException yourself, as shown in the putTask() and getTask() methods in Listing 1. Doing so makes your method responsive to interruption as well and often requires nothing more than adding InterruptedException to your throws clause.
Listing 1. Propagating InterruptedException to callers by not catching it


public class TaskQueue {
    private static final int MAX_TASKS = 1000;

    private BlockingQueue<Task> queue
        = new LinkedBlockingQueue<Task>(MAX_TASKS);

    public void putTask(Task r) throws InterruptedException {
        queue.put(r);
    }

    public Task getTask() throws InterruptedException {
        return queue.take();
    }
}

Don’t swallow interrupts
Sometimes throwing InterruptedException is not an option, such as when a task defined by Runnable calls an interruptible method. In this case, you can’t rethrow InterruptedException, but you also do not want to do nothing. When a blocking method detects interruption and throws InterruptedException, it clears the interrupted status. If you catch InterruptedException but cannot rethrow it, you should preserve evidence that the interruption occurred so that code higher up on the call stack can learn of the interruption and respond to it if it wants to. This task is accomplished by calling interrupt() to “reinterrupt” the current thread, as shown in Listing 3. At the very least, whenever you catch InterruptedException and don’t rethrow it, reinterrupt the current thread before returning.
Restoring the interrupted status after catching InterruptedException :


public class TaskRunner implements Runnable {
    private BlockingQueue<Task> queue;

    public TaskRunner(BlockingQueue<Task> queue) {
        this.queue = queue;
    }

    public void run() {
        try {
             while (true) {
                 Task task = queue.take(10, TimeUnit.SECONDS);
                 task.execute();
             }
         }
         catch (InterruptedException e) {
             // Restore the interrupted status
             Thread.currentThread().interrupt();
         }
    }
}

The worst thing you can do with InterruptedException is swallow it — catch it and neither rethrow it nor reassert the thread’s interrupted status. The standard approach to dealing with an exception you didn’t plan for — catch it and log it — also counts as swallowing the interruption because code higher up on the call stack won’t be able to find out about it. (Logging InterruptedException is also just silly because by the time a human reads the log, it is too late to do anything about it.) Listing 4 shows the all-too-common pattern of swallowing an interrupt:

Swallowing an interrupt — don’t do this :


// Don't do this
public class TaskRunner implements Runnable {
    private BlockingQueue<Task> queue;

    public TaskRunner(BlockingQueue<Task> queue) {
        this.queue = queue;
    }

    public void run() {
        try {
             while (true) {
                 Task task = queue.take(10, TimeUnit.SECONDS);
                 task.execute();
             }
         }
         catch (InterruptedException swallowed) {
             /* DON'T DO THIS - RESTORE THE INTERRUPTED STATUS INSTEAD */
         }
    }
}

If you cannot rethrow InterruptedException, whether or not you plan to act on the interrupt request, you still want to reinterrupt the current thread because a single interruption request may have multiple “recipients.” The standard thread pool (ThreadPoolExecutor) worker thread implementation is responsive to interruption, so interrupting a task running in a thread pool may have the effect of both canceling the task and notifying the execution thread that the thread pool is shutting down. If the task were to swallow the interrupt request, the worker thread might not learn that an interrupt was requested, which could delay the application or service shutdown.

More info :
http://www.ibm.com/developerworks/library/j-jtp05236/

Your program dies with “main” thread

main thread is not really main(adjective) it is just main(noun).

When a Java Virtual Machine starts up, there is usually a single non-daemon thread (which typically calls the method named main of some designated class). The Java Virtual Machine continues to execute threads until either of the following occurs:

  • The exit method of class Runtime has been called and the security manager has permitted the exit operation to take place.
  • All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.

The java program terminates when all non-daemon threads has been terminated ,it doesn’t have to be the main thread.or when System.exit() or Runtime.exit() is invoked.

You can throw and catch checked exception from a thread

The thread can’t throw the exception to any other thread (nor to the main thread). and you cannot make the inherited run() method throw any checked exceptions since you can only throw less than the inherited code, not more.
Code in below catch block won’t work :

package test.exec;

public class TestThrdException {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Thread myThread = new MyThread();
		try {
			myThread.start();
		} catch (Exception e) {
			System.out.println("Exception Catched");
			e.printStackTrace();
		}
	}

}

class MyThread extends Thread {
	public void run() {
		throw new RuntimeException();
	}
}

So what can you do ??

Use Callable :
To be able to send the exception to the parent thread, you can put your background thread in a Callable (it allows throwing also checked exceptions) which you then pass to the submit method of some Executor. The submit method will return a Future which you can then use to get the exception (its get method will throw an ExecutionException which contains the original exception).

Wait and notify :

public class ThingRunnable implements Runnable {
    private SomeListenerType listener;
    // assign listener somewhere

    public void run() {
        try {
            while(iHaveMorePackets()) {
                doStuffWithPacket();
            }
        } catch(Exception e) {
            listener.notifyThatDarnedExceptionHappened(...);
        }
    }
 }

The coupling comes from an object in the parent thread having to be of type SomeListenerType.

Use UncaughtExceptionHandler :

package test.exec;

public class TestThrdException {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Thread myThread = new MyThread();
		// Add the handler to the thread object
		myThread.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

			@Override
			public void uncaughtException(Thread t, Throwable e) {

				System.out.println("ERROR! An exception occurred in " + t.getName() + ". Cause: " + e.getMessage());
			}
		});
		myThread.start();
	}
}

class MyThread extends Thread {
	public void run() {
		throw new RuntimeException();
	}
}

Advertisements

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