I have read many posts on this. This answer https://stackoverflow.com/a/6701060/2359945 claimed a 100 bounty by suggesting to test the interrupted flag.
I tested this, and it does not work for me. So, the question remains, how do I detect a spurious wakeup, or is it not possible? Thank you.
class TestSpuriousWakeup {
static Thread t1, tInterrupt, tNotify;
// spawn one thread that will be interrupted and be notified
// spawn one thread that will interrupt
// spawn one thread that will notify
public static void main(String[] args) {
System.out.println("*** main Starting");
initThreads();
try {
t1.start();
Thread.sleep(2000);
tNotify.start();
tNotify.join();
Thread.sleep(2000);
tInterrupt.start();
tInterrupt.join();
t1.join();
} catch (InterruptedException e) {
System.out.println("*** Unexpected interrupt in main");
}
System.out.println("*** main Ended.");
}
private static void initThreads() {
t1 = new Thread() {
#Override
public void run() {
System.out.println("ThreadInterruptMe Started ...");
boolean stop = false;
Thread.interrupted(); // clear the interrupted flag
while (!stop) {
try {
System.out.println("ThreadInterruptMe Sleeping 5000ms ...");
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("ThreadInterruptMe InterruptedException e!");
System.out.println("ThreadInterruptMe e.getCause => " + e.getCause());
System.out.println("ThreadInterruptMe e.getLocalizedMessage => " + e.getLocalizedMessage());
stop = Thread.interrupted();
if (stop) {
System.out.println("ThreadInterruptMe was INTERRUPTED because Thread.interrupted() is true"); // never happens
} else {
System.out.println("ThreadInterruptMe was NOTIFIED because Thread.interrupted() is false"); // always happens
}
} finally {
Thread.interrupted(); // clear the interrupted flag
System.out.println("ThreadInterruptMe InterruptedException finally");
}
}
System.out.println("ThreadInterruptMe Ended.");
}
};
tInterrupt = new Thread() {
#Override
public void run() {
System.out.println(" ThreadInterruptYou Started ... interrupting now!");
t1.interrupt();
System.out.println(" ThreadInterruptYou Ended.");
}
};
tNotify = new Thread() {
#Override
public void run() {
System.out.println(" ThreadNotifyYou Started ... notifying now!");
t1.interrupt();
System.out.println(" ThreadNotifyYou Ended.");
}
};
}
}
Output:
*** main Starting
ThreadInterruptMe Started ...
ThreadInterruptMe Sleeping 5000ms ...
ThreadNotifyYou Started ... notifying now!
ThreadInterruptMe InterruptedException e!
ThreadNotifyYou Ended.
ThreadInterruptMe e.getCause => null
ThreadInterruptMe e.getLocalizedMessage => sleep interrupted
ThreadInterruptMe was NOTIFIED because Thread.interrupted() is false
ThreadInterruptMe InterruptedException finally
ThreadInterruptMe Sleeping 5000ms ...
ThreadInterruptYou Started ... interrupting now!
ThreadInterruptMe InterruptedException e!
ThreadInterruptMe e.getCause => null
ThreadInterruptMe e.getLocalizedMessage => sleep interrupted
ThreadInterruptMe was NOTIFIED because Thread.interrupted() is false
ThreadInterruptMe InterruptedException finally
ThreadInterruptMe Sleeping 5000ms ...
ThreadInterruptYou Ended.
ThreadInterruptMe InterruptedException finally
ThreadInterruptMe Sleeping 5000ms ...
ThreadInterruptMe InterruptedException finally
ThreadInterruptMe Sleeping 5000ms ...
<infinite loop>
What spurious wakeups are not
sleep() is not subject to spurious wakeups. The low-level system call it uses to sleep may be, but Java takes care of this detail for you, re-entering the system call if it's woken up prematurely. As a user you are not exposed to spurious wakeups.
Spurious wakeups are also unrelated to thread interruption. That is a separate tool. Threads are never "spuriously interrupted". If your thread is interrupted, that means somebody somewhere called Thread.interrupt() on your thread. Find that code and you will have the culprit.
What spurious wakeups are
If you want to test spurious wakeups, run tests with Object.wait() instead, since that's the classic method that suffers from them.
The naïve way of using wait() is to simply call it, expecting that it will only return when some other thread calls notify(). For example, a message sending loop might be:
for (;;) {
synchronized (monitor) {
if (queue.isEmpty()) { // incorrect
monitor.wait();
}
}
send(queue.remove());
}
This will fail if wait() spuriously wakes up without a message having been added to the queue. The solution is to add a loop around the wait() to verify the condition every time the thread is woken up.
for (;;) {
synchronized (monitor) {
while (queue.isEmpty()) { // correct
monitor.wait();
}
}
send(queue.remove());
}
The simplest way to simulate a spurious wakeup, then, is to simply call notify() without changing the loop condition.
synchronized (monitor) {
monitor.notify();
}
This will have the exact same effect on the thread performing wait() as if it encountered a spurious wakeup. The incorrect code using if won't realize the queue is still empty and will crash. The correct code using while will re-check the condition and safely re-enter the wait() call.
You detect a spurious wakeup by re-testing the predicate.
A wakeup is spurious if there is no reason for the wakeup. A wakeup is not spurious if some other thread intentionally woke you.
Or, to put it even more simply: If the thing you were waiting for hasn't happened, the wakeup was spurious. If the thing you were waiting for has happened, the wakeup was not spurious. You have to be able to check whether the thing you were waiting or has happened or not -- otherwise, how did you know you had to wait for it in the first place?
So before a thread intentionally wakes you, have it set some synchronized variable that you check when you wake up. If that variable is set, then the wakeup was not spurious, and you clear the flag. If it is not set, then the wakeup was spuroius, and you typically ignore the wakeup.
So, the flow goes as follows:
To wake/signal/interrupt at thread:
Acquire a lock or enter a synchronized block.
Set the boolean predicate to true.
Wake the thread.
Release the lock or exit the synchronized block.
(If desired, the order of 3 and 4 can be swapped.)
To wait for something to happen:
Acquire a lock or enter a synchronized block.
Set the boolean predicate to false (or check it if it was already set).
Wait, releasing the lock. When woken, reacquire the lock (or re-enter a synchronized block).
Check the predicate to see if the wake is spurious. If the predicate is false, go to step 3.
You now know the wakeup was not spurious. Release the lock or exit the synchronized block.
Related
Driver.java
public class Driver {
static Object obj = new Object();
public static void main(String [] args) throws InterruptedException
{
Thread thr = new Thread(new Runnable(){
#Override
public void run() {
System.out.println("Thread 1: Waiting for available slot.");
synchronized(obj){
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 1: Found slot!");
long x = 0;
while(x < Integer.MAX_VALUE) x++;
System.out.println("Thread 1: Completed processing.");
System.out.println("Thread 1: Notifying other waiting threads.");
obj.notify();
}
}
});
Thread thr2 = new Thread(new Runnable(){
#Override
public void run() {
System.out.println("Thread 2: Waiting for available slot.");
synchronized(obj){
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Thread 2: Found slot!");
long x = 0;
while(x < Integer.MAX_VALUE) x++;
System.out.println("Thread 2: Completed processing.");
System.out.println("Thread 2: Notifying other waiting threads.");
obj.notify();
}
}
});
thr.start();
thr2.start();
System.out.println("Main Thread: All processing units busy.");
// Thread.sleep(2000); // Enable this and disable the other Thread.sleep(...) and NOW we are good. But again, 'why?' is the question.
synchronized(obj){
Thread.sleep(2000); // This causes a failure. Move it outside the synchronized and it will work why?
System.out.println("Main Thread: Found ONLY 1 available slot.");
obj.notify();
obj.wait(); // JVM should catch this as the last request so it has the least priority.
System.out.println("Main Thread: Finished and exiting...");
}
}
}
The code above will not notify the Threads because of the following line:
Thread.sleep(2000); // This causes a failure. Move it outside the synchronized and it will work why?
Please take a look at this line in context with the whole class. I am having hard time pinpointing to the reason why this simple proof-of-concept would fail if that line is placed inside ther synchronized block in the Main Thread.
Thank you
The problem is not the sleep but rather that the main thread almost always acquires the lock before one (and occasionally both) of the created threads does. If you print just inside the synchronized blocks it's much more clear what is going on:
synchronized(obj) {
System.out.println("this thread acquired the lock");
You'll see the output is almost always Thread #1, then the main thread, and finally Thread #2 after Thread #1 completes (but main has already returned).
If you run it enough times sometimes both child threads do acquire the lock first and it completes.
The reason moving the sleep to outside the synchronized block in the main thread works is it allows both child threads to reach their respective wait statements.
Read the doc.
Wakes up a single thread that is waiting on this object's
monitor.
If it is sleeping then it is not waiting.
There is other related problem, it is not possible to reach the notify line while the other thread is in the sleep as it keeps the monitor (lock) and the other thread can't run inside the synchronized block. This is always that way as both wait and notify must be run inside related syncrhonized blocks (against the same monitor).
sleep holds the lock, but wait doesn't. so when your main thread is sleeping, both thr and thr2 can't get the lock until main thread notifies them. At that moment, they start to wait and can't receive any notify()
The problem is that sleep does not release the monitor, that is: while the main thread is sleeping, all the other threads cannot enter the synchronized block, so they are basically sleeping with the main thread.
The moment the main thread wakes up, it does notify, but since no one yet entered the wait() position, no one is listening. Then the main thread waits and therefore releases the monitor, so now all threads can proceed to the wait() state, but no one is left to wake them up. -> Deadlock
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.
I want to interrupt a thread, but invoking interrupt() doesn't seem to work. Below is the sample code:
public class BasicThreadrRunner {
public static void main(String[] args) {
Thread t1 = new Thread(new Basic(), "thread1");
t1.start();
Thread t3 = new Thread(new Basic(), "thread3");
Thread t4 = new Thread(new Basic(), "thread4");
t3.start();
t1.interrupt();
t4.start();
}
}
class Basic implements Runnable{
public void run(){
while(true) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.err.println("thread: " + Thread.currentThread().getName());
//e.printStackTrace();
}
}
}
}
but the output looks like thread 1 is still running. Can anyone explain this as well as how interrupt() works? Thanks!
The thread is still running simply because you catch InterruptedException and keep running. interrupt() primarily sets a flag in the Thread object, which you can check with isInterrupted(). It also causes some methods -- sleep(), join Object.wait(), in particular -- to return immediately by throwing an InterruptedException. It also causes some I/O operations to immediately terminate. If you're seeing the printouts from your catch block, then you can see that interrupt() is working.
As others have said, you catch the interrupt, but do nothing with it. What you need to do is propagate the interrupt using logic such as,
while(!Thread.currentThread().isInterrupted()){
try{
// do stuff
}catch(InterruptedException e){
Thread.currentThread().interrupt(); // propagate interrupt
}
}
Using looping logic, such as while(true) is just lazy coding. Instead, poll the thread's interrupted flag in order to determine termination via interruption.
++1, in addition to other answers. I believe the misconception about this was that it seemed the try/catch block finished its job after the Thread.sleep(1000); call i.e. try to sleep for 1000ms, catch anything that might interrupt my sleep attempt.
What is happening actually is that the try/catch block is still very much active while sleeping i.e. try to sleep for 1000ms, catch anything that might interrupt during my sleep
Hence the reason why the exception is being caught immediately (and afterwards) since the thread barely just started its sleep.
I know that finally blocks in deamon threads would not be executed. But my meticulous nature tries to understand why and what happens in JVM so special that it could not call the code under this block.
I think that it somehow related to call stack that it whould not unwind, but don't know how. Can someone please shed some light on this.
Thanks.
Who says that finally blocks in daemon threads don't execute? This is not true in general.
What you might have heard that a finally block is not guaranteed to be executed when a JVM is shut down during the execution of the try (or catch) block. That is correct (and it can easily happen to daemon threads).
But again: during normal operation, there is nothing that stops finally blocks from executing normally in daemon threads: they are not handled differently.
The shutdown problem is easy: when the JVM is asked to shut down or even forced to shut down, then it may simply not be able to execute any more statements.
For example, on POSIX-y operating systems, signal 9 (SIGKILL) forces an application to quit, giving it no chance to do any cleanup (this is why signal 15 (SIGTERM) is preferred, usually). In this case, the JVM can't execute the finally block, because the OS won't let it run any longer.
If the JVM exits while the try or catch code is being executed, then the finally block may not execute.
Normal Shutdown - this occurs either when the last non-daemon thread exits OR when Runtime.exit()
When a thread exits, the JVM performs an inventory of running threads, and if the only threads that are left are daemon threads, it initiates an orderly shutdown. When the JVM halts, any remaining daemon threads are abandoned finally blocks are not executed, stacks are not unwound the JVM just exits. Daemon threads should be used sparingly few processing activities can be safely abandoned at any time with no cleanup. In particular, it is dangerous to use daemon threads for tasks that might perform any sort of I/O. Daemon threads are best saved for "housekeeping" tasks, such as a background thread that periodically removes expired entries from an in-memory cache.
Last non-daemon thread exits example:
public class TestDaemon {
private static Runnable runnable = new Runnable() {
#Override
public void run() {
try {
while (true) {
System.out.println("Is alive");
Thread.sleep(10);
// throw new RuntimeException();
}
} catch (Throwable t) {
t.printStackTrace();
} finally {
System.out.println("This will never be executed.");
}
}
};
public static void main(String[] args) throws InterruptedException {
Thread daemon = new Thread(runnable);
daemon.setDaemon(true);
daemon.start();
Thread.sleep(100);
// daemon.stop();
System.out.println("Last non-daemon thread exits.");
}
}
Output:
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Is alive
Last non-daemon thread exits.
Is alive
Is alive
Is alive
Is alive
Is alive
I have created two non-daemon threads which will terminate before the rest two daemon threads.
One non-daemon thread wait for 20 sec,
one daemon thread wait for 40 sec,
one non-daemon thread sleep for 15 sec,
one daemon thread sleep for 30 sec,
one daemon thread sleep for 10 sec. The idea to terminate non-daemon threads before some daemon ones.
As the result suggests, the JVM will terminate as soon as there is no non-daemon thread alive, without executing the rest statements in the Runnable tasks of the daemon threads, even if they are inside finally block without throwing InterruptedException.
public class DeamonTest {
public static void main(String[] args) {
spawn(40000, Action.wait, true);
spawn(30000, Action.sleep, true);
spawn(10000, Action.sleep, true);
spawn(20000, Action.wait, false);
spawn(15000, Action.sleep, false);
}
enum Action {
wait, sleep
}
private static void spawn(final long time, final Action action,
boolean daemon) {
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Thread thread = Thread.currentThread();
try {
switch (action) {
case wait: {
synchronized (this) {
System.out.println(thread + " daemon="
+ thread.isDaemon() + ": waiting");
wait(time);
}
break;
}
case sleep: {
System.out.println(thread + " daemon="
+ thread.isDaemon() + ": sleeping");
Thread.sleep(time);
}
}
System.out.println(thread + " daemon=" + thread.isDaemon()
+ ": exiting");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(thread + " daemon=" + thread.isDaemon()
+ ": finally exiting");
}
}
});
thread.setDaemon(daemon);
thread.start();
}
}
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.