how does thread.interrupt() sets the flag? - java

From the docs:
The Interrupt Status Flag
The interrupt mechanism is implemented using an internal flag known as the interrupt status. Invoking Thread.interrupt sets this flag. When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to query the interrupt status of another, does not change the interrupt status flag.
By convention, any method that exits by throwing an InterruptedException clears interrupt status when it does so. However, it's always possible that interrupt status will immediately be set again, by another thread invoking interrupt.
I read these SO posts. But I don't think I have understood this correctly. so I tested this on a sample code below.
I have two threads running in this. one is main and other Thread-0 which is labeled t.
I call t.interrupt() and I call Thread.currentThread().isInterrupted() in the run method.
Where exactly is the flag set?
Does Thread Class maintains a static list of all the Threads that is currently running and by calling Thread.currentThread() I get the currentThread Object and check if it is interrupted?
If the Thread class itself has the boolean flag interrupted, how does it differentiate between two threads; example main and Thread-0 here. Is the static flag same to both the Threads?
what exact sequences of steps are happening, set flag, where is the look up and unset flag etc?
when I uncomment the block of code below (which is currently commented out), the program never stops. I do not understand why?
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class ThreadInterrupt {
public static void main(String[] args) throws InterruptedException {
System.out.println("Starting.");
Thread t = new Thread(new Runnable(){
#Override
public void run() {
Random ran = new Random();
for (int i = 0; i < 1E8; i++) {
/*try {
Thread.sleep(100);
} catch (InterruptedException e) {
System.out.println("we have been interrupted");
e.printStackTrace();
}*/
if (Thread.currentThread().isInterrupted()) {
System.out.println("Interrupted!");
break;
}
Math.sin(ran.nextDouble());
}
}
});
t.start();
Thread.sleep(500);
t.interrupt();
t.join();
System.out.println("Finished.");
}
}

when I uncomment the block of code below (which is currently commented
out), the program never stops. I do not understand why?
Note the javadoc of Thread#interrupt()
If this thread is blocked in an invocation of the wait(), wait(long),
or wait(long, int) methods of the Object class, or of the join(),
join(long), join(long, int), sleep(long), or sleep(long, int), methods
of this class, then its interrupt status will be cleared and it will
receive an InterruptedException.
So if you uncomment your code, the flag gets lifted and your if never executes.
Does Thread Class maintains a static list of all the Threads that is
currently running and by calling Thread.currentThread()
The Thread.currentThread() method is declared as (Oracle JDK 7)
public static native Thread currentThread();
In other words, it is natively implemented, probably in C code. We can assume, given the javadoc, that, somewhere, a reference to all threads is stored. The currently executing one is returned.
Similarly, the Thread#isInterrupted() method calls
private native boolean isInterrupted(boolean ClearInterrupted);
which is also natively implemented. But we can assume it uses some boolean-style flag.

Where exactly is the flag set?
The JVM Thread object keeps track of the flag.
Does Thread Class maintains a static list of all the Threads that is currently running and by calling Thread.currentThread() I get the currentThread Object and check if it is interrupted?
The Thread Class doesn't do it but the JVM does. Thread.currentThread() is a static method which returns the Thread object that is associated with the calling thread.
If the Thread class itself has the boolean flag interrupted, how does it differentiate between two threads; example main and Thread-0 here
It is an instance field not a static field. It is per Thread instance.
when I uncomment the block of code below (which is currently commented out), the program never stops. I do not understand why?
Because when you interrupt the thread, Thread.sleep(...) throws InterruptedException which clears the interrupt flag for the thread. You always should re-interrupt the thread once you catch InterruptedException.
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// _always_ reinterrupt the thread when you catch InterruptedException
Thread.currentThread().interrupt();
System.out.println("we have been interrupted");
e.printStackTrace();
}

Related

my own blocking queue for producer consumer [duplicate]

I am using multi-threading in java for my program.
I have run thread successfully but when I am using Thread.wait(), it is throwing java.lang.IllegalMonitorStateException.
How can I make a thread wait until it will be notified?
You need to be in a synchronized block in order for Object.wait() to work.
Also, I recommend looking at the concurrency packages instead of the old school threading packages. They are safer and way easier to work with.
EDIT
I assumed you meant Object.wait() as your exception is what happens when you try to gain access without holding the objects lock.
wait is defined in Object, and not it Thread. The monitor on Thread is a little unpredictable.
Although all Java objects have monitors, it is generally better to have a dedicated lock:
private final Object lock = new Object();
You can get slightly easier to read diagnostics, at a small memory cost (about 2K per process) by using a named class:
private static final class Lock { }
private final Object lock = new Lock();
In order to wait or notify/notifyAll an object, you need to be holding the lock with the synchronized statement. Also, you will need a while loop to check for the wakeup condition (find a good text on threading to explain why).
synchronized (lock) {
while (!isWakeupNeeded()) {
lock.wait();
}
}
To notify:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
It is well worth getting to understand both Java language and java.util.concurrent.locks locks (and java.util.concurrent.atomic) when getting into multithreading. But use java.util.concurrent data structures whenever you can.
I know this thread is almost 2 years old but still need to close this since I also came to this Q/A session with same issue...
Please read this definition of illegalMonitorException again and again...
IllegalMonitorException is thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
This line again and again says, IllegalMonitorException comes when one of the 2 situation occurs....
1> wait on an object's monitor without owning the specified monitor.
2> notify other threads waiting on an object's monitor without owning the specified monitor.
Some might have got their answers... who all doesn't, then please check 2 statements....
synchronized (object)
object.wait()
If both object are same... then no illegalMonitorException can come.
Now again read the IllegalMonitorException definition and you wont forget it again...
Based on your comments it sounds like you are doing something like this:
Thread thread = new Thread(new Runnable(){
public void run() { // do stuff }});
thread.start();
...
thread.wait();
There are three problems.
As others have said, obj.wait() can only be called if the current thread holds the primitive lock / mutex for obj. If the current thread does not hold the lock, you get the exception you are seeing.
The thread.wait() call does not do what you seem to be expecting it to do. Specifically, thread.wait() does not cause the nominated thread to wait. Rather it causes the current thread to wait until some other thread calls thread.notify() or thread.notifyAll().
There is actually no safe way to force a Thread instance to pause if it doesn't want to. (The nearest that Java has to this is the deprecated Thread.suspend() method, but that method is inherently unsafe, as is explained in the Javadoc.)
If you want the newly started Thread to pause, the best way to do it is to create a CountdownLatch instance and have the thread call await() on the latch to pause itself. The main thread would then call countDown() on the latch to let the paused thread continue.
Orthogonal to the previous points, using a Thread object as a lock / mutex may cause problems. For example, the javadoc for Thread::join says:
This implementation uses a loop of this.wait calls conditioned on this.isAlive. As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Since you haven't posted code, we're kind of working in the dark. What are the details of the exception?
Are you calling Thread.wait() from within the thread, or outside it?
I ask this because according to the javadoc for IllegalMonitorStateException, it is:
Thrown to indicate that a thread has attempted to wait on an object's monitor or to notify other threads waiting on an object's monitor without owning the specified monitor.
To clarify this answer, this call to wait on a thread also throws IllegalMonitorStateException, despite being called from within a synchronized block:
private static final class Lock { }
private final Object lock = new Lock();
#Test
public void testRun() {
ThreadWorker worker = new ThreadWorker();
System.out.println ("Starting worker");
worker.start();
System.out.println ("Worker started - telling it to wait");
try {
synchronized (lock) {
worker.wait();
}
} catch (InterruptedException e1) {
String msg = "InterruptedException: [" + e1.getLocalizedMessage() + "]";
System.out.println (msg);
e1.printStackTrace();
System.out.flush();
}
System.out.println ("Worker done waiting, we're now waiting for it by joining");
try {
worker.join();
} catch (InterruptedException ex) { }
}
In order to deal with the IllegalMonitorStateException, you must verify that all invocations of the wait, notify and notifyAll methods are taking place only when the calling thread owns the appropriate monitor. The most simple solution is to enclose these calls inside synchronized blocks. The synchronization object that shall be invoked in the synchronized statement is the one whose monitor must be acquired.
Here is the simple example for to understand the concept of monitor
public class SimpleMonitorState {
public static void main(String args[]) throws InterruptedException {
SimpleMonitorState t = new SimpleMonitorState();
SimpleRunnable m = new SimpleRunnable(t);
Thread t1 = new Thread(m);
t1.start();
t.call();
}
public void call() throws InterruptedException {
synchronized (this) {
wait();
System.out.println("Single by Threads ");
}
}
}
class SimpleRunnable implements Runnable {
SimpleMonitorState t;
SimpleRunnable(SimpleMonitorState t) {
this.t = t;
}
#Override
public void run() {
try {
// Sleep
Thread.sleep(10000);
synchronized (this.t) {
this.t.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Thread.wait() call make sense inside a code that synchronizes on Thread.class object. I don't think it's what you meant.
You ask
How can I make a thread wait until it will be notified?
You can make only your current thread wait. Any other thread can be only gently asked to wait, if it agree.
If you want to wait for some condition, you need a lock object - Thread.class object is a very bad choice - it is a singleton AFAIK so synchronizing on it (except for Thread static methods) is dangerous.
Details for synchronization and waiting are already explained by Tom Hawtin.
java.lang.IllegalMonitorStateException means you are trying to wait on object on which you are not synchronized - it's illegal to do so.
Not sure if this will help somebody else out or not but this was the key part to fix my problem in user "Tom Hawtin - tacklin"'s answer above:
synchronized (lock) {
makeWakeupNeeded();
lock.notifyAll();
}
Just the fact that the "lock" is passed as an argument in synchronized() and it is also used in "lock".notifyAll();
Once I made it in those 2 places I got it working
I received a IllegalMonitorStateException while trying to wake up a thread in / from a different class / thread. In java 8 you can use the lock features of the new Concurrency API instead of synchronized functions.
I was already storing objects for asynchronous websocket transactions in a WeakHashMap. The solution in my case was to also store a lock object in a ConcurrentHashMap for synchronous replies. Note the condition.await (not .wait).
To handle the multi threading I used a Executors.newCachedThreadPool() to create a thread pool.
Those who are using Java 7.0 or below version can refer the code which I used here and it works.
public class WaitTest {
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
public void waitHere(long waitTime) {
System.out.println("wait started...");
lock.lock();
try {
condition.await(waitTime, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
lock.unlock();
System.out.println("wait ends here...");
}
public static void main(String[] args) {
//Your Code
new WaitTest().waitHere(10);
//Your Code
}
}
For calling wait()/notify() on object, it needs to be inside synchronized block. So first you have to take lock on object then would be possible to call these function.
synchronized(obj)
{
obj.wait()
}
For detailed explanation:
https://dzone.com/articles/multithreading-java-and-interviewspart-2
wait(), notify() and notifyAll() methods should only be called in syncronized contexts.
For example, in a syncronized block:
syncronized (obj) {
obj.wait();
}
Or, in a syncronized method:
syncronized static void myMethod() {
wait();
}

How to stop/interrupt running thread from another method?

I am a total beginner to android and Java development, and I am currently trying to make a metronome.
The first problem I encountered after getting the sound playback to work, is that whenever the metronome played the app would stop responding - that's when I learned about threads and how I should use a new thread for my audio playback.
Creating a new thread helped and now the app runs fine, but I can't get the thread to stop/interrupt. I've read maybe 50 articles already about threads and interrupts and I can't figure it out.
Here is my 'Player' class code, which I've mostly copied from another Stack Overflow post (I have tried countless other ways and variations and none worked):
package com.example.t.firstapp;
import android.util.Log;
public class Player implements Runnable {
Thread backgroundThread;
Metronome m;
public void start() {
if (backgroundThread == null) {
backgroundThread = new Thread(this);
m = new Metronome();
backgroundThread.start();
}
}
public void stop() {
if (backgroundThread != null) {
backgroundThread.interrupt();
}
}
public void run() {
try {
Log.i("a", "Thread starting.");
while (!backgroundThread.isInterrupted()) {
m.play();
}
Log.i("b", "Thread stopping.");
throw new InterruptedException(); // ???
} catch (InterruptedException ex) {
// important you respond to the InterruptedException and stop processing
// when its thrown! Notice this is outside the while loop.
Log.i("c", "Thread shutting down as it was requested to stop.");
} finally {
backgroundThread = null;
}
}
}
Note the line marked with "???". I added that one myself because otherwise the "catch (InterruptedException ex)" returned an error.
Here is the relevant code from my MainActivity class:
public class MainActivity extends AppCompatActivity {
...
public Player p;
...
public void play() {
p = new Player();
p.start();
}
public void stop() {
p.stop();
}
}
Calling p.stop(); from within the method 'stop' doesn't actually do anything. This is where I get stuck. If I call p.stop() immediately after I start the thread, like this:
public void play() {
p = new Player();
p.start();
p.stop();
}
Then it works, and I see all of the relevant log messages from the Player class. Why doesn't p.stop() work when I call it from my 'stop' method? Is it because I am calling it from a different method, or is it because I am not calling it immediately?
Any help would be greatly appreciated since this is extremely frustrating. I have been studying and practicing Android development for only a week now, but I haven't done anything over the last 5 days but try to solve this problem. Thanks
You misunderstood the concept of interruption. Interupting is not some magical way of forcing the thread to stop, rather it will only work for methods that have interruption support - like sleeping.
Take a look at the Thread#interrupt() API, where it lists interrupt supported methods:
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
You can nicely implement your own methods with interrupt support, by contantly checking for the interrupt status.
Now let's see how we can solve your problem.
According to your comment, m.play() does not return, meaning, once m.play() is called, the while never checks if the thread has been interrupted; in turn it will never stop, since m.play() isn't implemented to support interrupts. This should also explain why the compiler complains that nobody throws an InterruptedException. (The reason it worked if interrupted immediately, is that the interrupt status is changed before it reaches the while... Think of it.)
Now, I assume that, if you will call m.stop(), m.play() will return, successfully rechecking for thread interruption. That's why it worked, as mentioned in comment.
But look, there's no real use of interrupting the thread - since all you have to do is call m.stop() and release the m.play(), just play and wait to return - which means stop has been called. Same to the while loop, drop it all the way.
public void run() {
Log.i("a", "Thread starting.");
m.play(); // blocks till stopped from some other thread...
Log.i("b", "Thread stopping.");
Log.i("c", "Thread shutting down as it was requested to stop.");
backgroundThread = null;
}
One case where I may see a use of the while and interrupt, if m.play() may return earlier than by calling m.stop() (say, by some exception), and you want to restart the metronome until stop is called; then a loop may be on the rescue, and interrupt may signal that it was actually stopped by calling m.stop().
public void run() {
Log.i("a", "Thread starting.");
while (!backgroundThread.isInterrupted()) {
m.play();
if(!backgroundThread.isInterrupted())
Log.i("b", "Stopped by exception, restarting....");
}
Log.i("c", "Thread stopping.");
Log.i("d", "Thread shutting down as it was requested to stop.");
backgroundThread = null;
}

why Interrupted exception thrown here...reason?

public class TwoThreads {
private static Object resource = new Object();
private static void delay(long n) {
try
{
Thread.sleep(n);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.print("StartMain ");
new Thread1().start();
delay(1000); //dealay 1
Thread t2 = new Thread2();
t2.start();
delay(1000); // delay 2
t2.interrupt(); //here its throwing exception
delay(1000); //delay 3
System.out.print("EndMain ");
}
static class Thread1 extends Thread {
public void run() {
synchronized (resource) {
System.out.print("Startl ");
delay(6000);
System.out.print("End1 ");
}
}
}
static class Thread2 extends Thread {
public void run() {
synchronized (resource) {
System.out.print("Start2 ");
delay(2000);
System.out.print("End2 ");
}
}
}
}
I just got confused here why t2.interrupt() is not throwing exception when t2 is waiting to acquire lock on resource object and interrupt() method might throw security exception then why compiler still allowing us to execute it without putting it into try catch block.
A synchronized block doesn't throw an InterruptedException and interrupting a thread blocking while attempting to acquire a monitor this way doesn't do anything.
If you want this functionality you need to use a Lock which has lockInterruptibly(), though this is not often used.
Acquires the lock unless the current thread is interrupted. Acquires
the lock if it is not held by another thread and returns immediately,
setting the lock hold count to one.
If the current thread already holds this lock then the hold count is
incremented by one and the method returns immediately.
If the lock is held by another thread then the current thread becomes
disabled for thread scheduling purposes and lies dormant until one of
two things happens:
The lock is acquired by the current thread; or Some other thread
interrupts the current thread. If the lock is acquired by the current
thread then the lock hold count is set to one.
If the current thread:
has its interrupted status set on entry to this method; or is
interrupted while acquiring the lock, then InterruptedException is
thrown and the current thread's interrupted status is cleared.
From Thread#interrupt():
If none of the previous conditions hold then this thread's interrupt status will be set.
If you checked t2.interrupted(), you'd see a true result, but the thread is blocking on entering the synchronized block, which doesn't trigger an InterruptedException.
A call to interrupt() may throw a SecurityException if the application's environment has set up restrictions on which threads can interact with others, but this doesn't apply in your simple example.
The question is unclear but I guess I understood it correct so I am attempting to answer.
syncrhonized blocks are NOT responsive to interrupts.
For that you can use explicit locks Lock, which has a method lockInterruptibly() which is responsive to interrupts.
lockInterruptibly() in Lock Interface
java.lang.Thread.interrupt() means Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
you have called sleep() on t2. that is the reason of getting interruptedException.

Why was task1 thread not interrupted

Assume the below code is executed with a debugger so that we can predict the order of execution.
t1 -- Here task1 starts working on some long task.
t2 --- task2 gets blocked # Syncronized statement because task1 is holding lock.
t3 -- task2 is interrupted but its missed because task2 is using intrinsic locks and hence cannot be interrupted # synchronized. (Renenterant.lockInterruptible() would have thrown InterruptedExecption).
t4 --- task1 is interrupted. However despite of doing the complex task in try catch block, InterruptedExecption was never thrown. Why is that ?
Code:
public class TestInteruptibility {
public static Object lock = new Object();
public static boolean spin = true;
public static void main(String[] args) {
Thread task1 = new Thread(new Task(), "Task1");
Thread task2 = new Thread(new Task(), "Task2");
Thread notifier1 = new Thread(new Notifier(), "Notifier1");
task1.start();
task2.start();
task2.interrupt();
task1.interrupt();
notifier1.start();
}
}
class Task implements Runnable {
public void run() {
synchronized (TestInteruptibility.lock) {
System.out.println("Performing Long Task");
try {
while (TestInteruptibility.spin) {
}
System.out.println("Finsihed Performing Long Task");
TestInteruptibility.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("I got interrupted while i was waiting # wait()");
}
System.out.println("Ending Task");
}
}
}
class Notifier implements Runnable {
public void run() {
synchronized (TestInteruptibility.lock) {
System.out.println("Performing notification");
TestInteruptibility.lock.notify();
System.out.println("Ending notification");
}
}
}
Basically, what interrupt() does is to set a flag in the Thread object. And you need to check it with isInterrupted(). Then you can handle this interrupt signal. It won't throw an InterruptedException in this situation.
Besides, it can cause some methods, for example, Thread.sleep(), Object.wait(), to return immediately and throw an InterruptedException. And you can get and InterruptedException in this situation.
From Java Concurrency in Practice, 7.1.1. Interruption:
A good way to think about interruption is that it does not actually interrupt a running thread; it just requests that the thread interrupt itself at the next convenient opportunity. (These opportunities are called cancellation points.) Some methods, such as wait, sleep, and join, take such requests seriously, throwing an exception when they receive an interrupt request or encounter an already set interrupt status upon entry. Well behaved methods may totally ignore such requests so long as they leave the interruption request in place so that calling code can do something with it. Poorly behaved methods swallow the interrupt request, thus denying code further up the call stack the opportunity to act on it.
In your above code, you are not waiting/sleeping. So you have to check isInterrupted() and handle interrupt signal yourself in the while loop.
while (TestInteruptibility.spin) {
if (Thread.currentThread().isInterrupted()) {
break;
}
}
References:
why interrupt() not work as expected and how does it work
What does java.lang.Thread.interrupt() do?
You have a busy while loop, that holds the lock (and never ends, unless you change spin's value somewhere). I suppose that task1 is still in the loop, therefore it doesn't notice the interruption. Task2 can't acquire the lock, so it blocks.
The way Task is implemented, it can only be interrupted in during the wait command, which comes after the loop.
BTW: if you are using the spin data member in different threads, then it should probably be declared as volatile. For similar thread safety reasons, lock should be declared as final.
When you call method interrupt() the result depends on the this thread is doing currently. If it is blocked on some interruptable method such as Object.wait(), then it will be interrupted immediately, which means that InterruptedException will be throw inside the thread. If thread is not blocked, but is doing some calculations, or it is block on some non-interruptable method such as InputStream.read() then InterruptedException is not thrown, but interrupted flag is set on thread instead. This flag will cause InterruptedException next time thread will call some interruptable method, but not now.
In your case threads task1 and task2 are spinning in infinite empty loops and thus are not blocked on any interruptable methods, so when you call interrupt() on then, no InterruptedException is thrown inside that threads, but interrupted flag is just set. You probably should change your task code to look like this:
while (TestInteruptibility.spin && !Thread.interrupted ()) {
}
then you will exit from the loop as long as somebody will call interrupt on task thread.

Java - Thread problem

My question is related to all those methods(including Thread.sleep(...)) which throw InterruptedException.
I found a statement on Sun's tutorial saying
InterruptedException is an exception that sleep throws when another thread interrupts the current thread while sleep is active.
Is that means that the interrupt will be ignored if the sleep is not active at the time of interrupt?
Suppose I have two threads: threadOne and threadTwo. threadOne creates and starts threadTwo. threadTwo executes a runnable whose run method is something like:
public void run() {
:
:
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
:
:
: // In the middle of two sleep invocations
:
:
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
:
:
}
After thread creation, threadOne interrupts threadTwo. Suppose the threadTwo is in the middle of two sleep invocations at the time of interrupt (when no sleep method was active), then will the second sleep method throw InterrupteException as soon as it is invoked?
If not, then will this interrupt will be ignored forever?
How to be sure that threadTwo will always know about the interrupt (doesn't matter whether its one of the sleep method is active or not)?
From javadoc:
If this thread is blocked in an
invocation of the wait(), wait(long),
or wait(long, int) methods of the
Object class, or of the join(),
join(long), join(long, int),
sleep(long), or sleep(long, int),
methods of this class, then its
interrupt status will be cleared and
it will receive an
InterruptedException.
If this thread is blocked in an I/O
operation upon an interruptible
channel then the channel will be
closed, the thread's interrupt status
will be set, and the thread will
receive a ClosedByInterruptException.
If this thread is blocked in a
Selector then the thread's interrupt
status will be set and it will return
immediately from the selection
operation, possibly with a non-zero
value, just as if the selector's
wakeup method were invoked.
If none of the previous conditions
hold then this thread's interrupt
status will be set.
This means that you have to check the interrupted status to be sure your thread knows about the interruption. This can be done with two methods: isInterrupted() and interrupted(). The last one clear the interrupted status.
Something like this:
while(!Thread.interrupted()) {
...
try {
Thread.sleep(10 * 1000);
} catch (InterruptedException e) {
return;
}
}
On Sun's Windows JDK, the thread will in fact throw InterruptedException when entering sleep():
public static final void main(String args[]) throws Exception {
final Thread main = Thread.currentThread();
Thread t = new Thread() {
#Override
public void run() {
main.interrupt();
}
};
t.start();
t.join();
Thread.sleep(1000);
System.out.println("Not interrupted!");
}
The API documentation of sleep() can be interpreted to mean that this is mandatory behaviour:
throws InterruptedException - if any
thread has interrupted the current
thread. The interrupted status of the
current thread is cleared when this
exception is thrown.
But that's not very clear, so I wouldn't depend on it and instead check isInterrupted() manually.
The Java documentation is a tad misleading. If the interrupted status of a thread is set, calling sleep() on that thread will cause an InterruptException to be thrown immediately.
This applies even if the thread was interrupted before sleep() was called.
As stated above, though, you can also check with Thread.isInterrupted() if you want to handle interrupts yourself.
The InterruptionException is only of interest during the sleep of the thread. It won't be thrown by the later sleep() call if the thread has been interupted anywhere before. Only the interuption at the time of the sleep() does matter because it breaks exactly that sleep() call.

Categories