class Thread3_1 extends Thread {
public static int count = 0;
String tname1;
public Thread3_1(String threadname) {
tname1 = threadname;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname1 + " : " + i);
count++;
if (count == 2) {
try {
sleep(1000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (isInterrupted()) {
System.out.println("Stop Thread");
return;
}
}
}
class Thread3_2 extends Thread {
String tname2;
public Thread3_2(String threadname) {
tname2 = threadname;
}
#Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname2 + " : " + i);
if (i == 5) {
Thread.currentThread().interrupt();
System.out.println("Going to interrupt Thread1");
}
}
}
}
Thread is executing after giving interrupt()
Interrupting a thread just sets an interrupt flag to true for this thread.
It's the responsibility of the thread itself to regurlarly check the value of this flag and stop executing ASAP (by returning from the run() method) as soon as it's true.
When the interrupt flag is set while the thread is sleeping (or when it's blocked inside a bocking call like wait(), await(), etc.), an InterruptedException is thrown by the blocking method. It's also the responsibility of the thread to cacth this exception and stop executing ASAP.
Your first thread regularly checks the flag and exits when it's true, but fails to do so when an InterruptedException is caught.
Your second thread interrupts itself, but doesn't return from its run() method when it does so.
You interrupt Thread3_2 and not Thread3_1.
In the run method of Thread3_2 you are calling
Thread.currentThread().interrupt();
This will send an interrupt to the current executing thread and this is an instance of Thread3_2. If you want to interrupt Thread3_1 you need a reference to that thread.
For example:
class Thread3_2 extends Thread{
Thread threadToInterrupt;
public Thread3_2(Thread threadToInterrupt) {
this.threadToInterrupt = threadToInterrupt;
}
#Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname2+ " : " +i);
if(i == 5){
threadToInterrupt.interrupt();
System.out.println("Going to interrupt Thread1");
}
}
}
}
The thread you are interrupting must be designed to deal with the interruption request, by exiting gracefully from the run() method. That means making sure that InterruptedExceptions cause the code to break out of loops. It also means checking the interrupted flag periodically inside loops. There are other scenarios which are harder to deal with, such as non-interruptible IO operations.
It is also a good practice that the target thread re-marks itself as interrupted, so that the callers up in the call stack also get an indication of the interruption (Use Thread.currentThread().interrupt() in catch statements).
As noted above you need to interrupt Thread3_1 and not Thread3_2.
After applying this fix you will still have one issue left:
try {
sleep(1000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
So if at sleep interrupt happens, interrupt flag will be cleared and isInterrupted() method will return false, so below condition will not be met:
if (isInterrupted()) {
System.out.println("Stop Thread");
return;
}
So you need to handle this in catch block as well, i.e. return if in catch (got interrupted)
From the Java Tutorials:
Many methods that throw InterruptedException, such as sleep, are
designed to cancel their current operation and return immediately when
an interrupt is received.
What if a thread goes a long time without invoking a method that
throws InterruptedException? Then it must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received.*
*In other words: Other methods that do not throw InterruptedException must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received.
Explained here: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Related
I was trying out the below code, I interrupted a user thread, when I print the value of isInterrupted it is returning false, I didn't got a single true value, over here the flag will get reset when the exception has been caught or on calling interrupted method.
Secondly, as per my understanding sleep method should throw and interruptedException in each iteration, the value in catch print, but it is throwing only once.
class ThreadInterruptt extends Thread
{
public void run()
{
for(int i = 0; i<100;i++)
{
try {
Thread.sleep(1000);
System.out.println(i);
System.out.println(isInterrupted());
} catch (InterruptedException e) {
System.out.println("Thread Interrupted");
}
}
}
}
public class ThreadInterrupt {
public static void main(String ag[]) throws InterruptedException
{
ThreadInterruptt t = new ThreadInterruptt();
t.start();
Thread.sleep(100);
t.interrupt();
}
}
You wouldn't ever get to the isInterrupted() check if you are interrupted: Thread.sleep() would have thrown an exception, and also it clears the interrupted status of the Thread, as described in the Javadoc.
And you're then discarding the fact the thread was interrupted (because you don't reset the interrupted flag on catching the exception), so it's not interrupted on the next iteration.
I am trying to implement a blocking queue(only on consumer side) with ReentrantLock and conditions but am running into a state where the JVM doesn't terminate. The strange thing is that one thread gets interrupted but the other doesn't. I am sure I am making some mistake but just can't figure out what.
EDIT:
Main Question: Why does only one thread throw an interruptedexception when both the threads are blocking on condition.await
So the code below is just an example that i created. The main problem was to develop a producer-consumer implementation in which I had to create a simulation class which spawned two kinds of threads, customers and cooks, which were synchronized based on a Reentrant lock. After some operations were performed(customers adding orders and cooks performing serving those orders),I call join on customer threads to make sure that all orders have been processed and then to stop the cook threads, I called interrupt on the cook threads to terminate them. But only one thread throws interruptedexception and the second one doesn't. Why is that? since both the threads are blocking on await.
My code is as follows:
Thread class:
public class InterruptedThread implements Runnable{
private final Lock lock;
private final Condition condition;
private final Queue<Integer> orderQueue;
public InterruptedThread(Lock lock, Condition condition,Queue<Integer> orderQueue)
{
this.lock = lock;
this.condition = condition;
this.orderQueue = orderQueue;
}
#Override
public void run() {
try{
while(true)
{
this.lock.lockInterruptibly();
while(orderQueue.size() == 0 && !Thread.currentThread().isInterrupted())
{
System.out.println("Inside blocking wait" + Thread.currentThread().getName());
condition.await();
}
int i = orderQueue.poll().intValue();
System.out.println("Value read:" + i + "by thread" + Thread.currentThread().getName());
this.lock.unlock();
}
}
catch(InterruptedException ex)
{
System.out.println("Interrupted exception" + Thread.currentThread().getName());
this.condition.signalAll();
Thread.currentThread().interrupt();
}
}
}
Main class:
public class ExplicitLockCondition {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Queue<Integer> orderQueue = new LinkedList<>();
Lock lock = new ReentrantLock();
Condition testCondition = lock.newCondition();
Thread[] ths = new Thread[2];
for(int i=0; i<ths.length;i++)
{
ths[i] = new Thread(new InterruptedThread(lock, testCondition,orderQueue));
ths[i].start();
}
lock.lock();
orderQueue.add(1);
lock.unlock();
lock.lock();
orderQueue.add(2);
lock.unlock();
try {
Thread.currentThread().sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(ExplicitLockCondition.class.getName()).log(Level.SEVERE, null, ex);
}
lock.lock();
orderQueue.add(-99);
lock.unlock();
for(int i=0; i<ths.length;i++)
{
ths[i].interrupt();
}
System.out.println("After loop exited!!!");
for(int i=0; i<ths.length;i++)
{
System.out.println("Interrupted thread:" + ths[i].getName() +"with interrupt flag:" + ths[0].isInterrupted());
}
for(int i=0; i<ths.length;i++)
{
try {
ths[i].join();
} catch (InterruptedException ex) {
Logger.getLogger(ExplicitLockCondition.class.getName()).log(Level.SEVERE, null, ex);
}
}
System.out.println("Program exited!!!");
}
}
You have
condition.await();
but the only place you signal it is in the catch block.
In a typical run of your application, your InterruptedThread (let's call it it1) will enter the while loop and await on the condition, putting itself in a waiting state. Your main thread will do a bunch of things and eventually interrupt it1. You'll note the javadoc of Condition#await() states
In all cases, before this method can return the current thread must
re-acquire the lock associated with this condition.
So thread it2 reacquires the lock and because it's been interrupted
If the current thread:
has its interrupted status set on entry to this method; or
is interrupted while waiting and interruption of thread suspension is supported,
then InterruptedException is thrown and the current thread's
interrupted status is cleared.
So execution leaves the while block and goes to the catch. During this time, your thread it2 still owns the lock, since nothing unlocked it. The catch block then calls
this.condition.signalAll();
which signals the condition. Thread it1 then completes normally. However, the Lock is still locked and nothing can acquire it which is why your other InterruptedThread cannot continue from within its
condition.await();
You basically have to manage locking and unlocking your Lock better.
a) you never signal the condition after you insert a value to your queue
b) your thread will leave
while(orderQueue.size() == 0 && !Thread.currentThread().isInterrupted())
if it is interrupted, and then tried to poll the value from the queue.
If there is no value there, the null will be returned and you end up with uncaught null pointer exception but the lock will never be unlock.
Allways
lock.lock()l
try {
...
} finally {
lovk.unlovk();
}
Why doesn't thread wait for notify()? The thread starts and then goes to the waiting pool, but it proceeds to execute after that moment.
public class JavaApplication2 {
public static void main(String [] args) {
ThreadB b = new ThreadB();
synchronized(b) {
b.start();
try {
System.out.println("1");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
synchronized(this) {
total += 1;
//notify();
}
}
}
You are synchronizing on the thread object itself, which is wrong usage. What happens is that the dying thread-of-execution always calls notify on its Thread object: Thread.join relies on this. Therefore it is clear why you get the same behavior with and without your own notify in there.
Solution: use a separate object for thread coordination; this is the standard practice.
The method notifyAll() is invoked for the Thread object of the terminating thread. This fact is strangely documented in the description of the Thread.join, with the following sentence:
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Thus, if you don't explicitly read the description of join, which you don't necessarily have to, you don't get to know the reason for the strange behavior.
You cannot depend on not returning from wait until a notify: "interrupts and spurious wakeups are possible". In general, you should wrap a wait call in a loop while the thread should go on waiting.
If you try your code synchronizing on any object other that ThreadB you will find it never terminates. This is because there is a hidden call to notify.
Although I am not aware of anywhere that this is specified, Thread notifies itself when it ends. This is implicit in the way the join method is implemented. This is the code for join:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
(From the JDK7 source code)
As you can see, the calls to wait only make sense if somewhere there is a call to notify that is called after the thread ends. The same call to notify is what allows your program to terminate.
You have nested synchronized {} constructs in the two places. These constructs seem doing something weird: the thread does not react into notify at all and only resumes when ThreadB (b) terminates. Remove this:
public class JavaApplication2 {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println(" ### Waiting for notify");
synchronized (b) {
b.wait();
}
System.out.println(" ### Notified");
} catch (InterruptedException e) {
}
System.out.println("### Total is: " + b.total);
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
total += 1;
System.out.println(" *** Ready to notify in 5 secs");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** Notification sent");
synchronized (this) {
notify();
}
System.out.println(" *** 5 sec post notification");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** ThreadB exits");
}
}
The code above probably works correctly: with notify() present the main thread resumes after 5 seconds and before we see the message that ThreadB terminates. With notify() commented out the main thread resumes after 10 seconds and after the message about the termination of the ThreadB because notify() is called anywhay from the other code. Marko Topolnik explains why and from where this "behind the scene" notify() call comes from.
I was doing the same testing on the wait/notify opertaions while reading OCP SE 7, good catch. I think we should let the authoer to explain.
I'm trying to understand how threads work, and I wrote a simple example where I want to create and start a new thread, the thread, display the numbers from 1 to 1000 in the main thread, resume the secondary thread, and display the numbers from 1 to 1000 in the secondary thread. When I leave out the Thread.wait()/Thread.notify() it behaves as expected, both threads display a few numbers at a time. When I add those functions in, for some reason the main thread's numbers are printed second instead of first. What am I doing wrong?
public class Main {
public class ExampleThread extends Thread {
public ExampleThread() {
System.out.println("ExampleThread's name is: " + this.getName());
}
#Override
public void run() {
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
}
}
public static void main(String[] args) {
new Main().go();
}
public void go() {
Thread t = new ExampleThread();
t.start();
synchronized(t) {
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
synchronized(t) {
t.notify();
}
}
}
You misunderstand how wait/notify works. wait does not block the thread on which it is called; it blocks the current thread until notify is called on the same object (so if you have threads A and B and, while in thread A, called B.wait(), this will stop thread A and not thread B - for as long as B.notify() is not called).
So, in your specific example, if you want main thread to execute first, you need to put wait() inside the secondary thread. Like this:
public class Main {
public class ExampleThread extends Thread {
public ExampleThread() {
System.out.println("ExampleThread's name is: " + this.getName());
}
#Override
public void run() {
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
}
}
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
}
}
public static void main(String[] args) {
new Main().go();
}
public void go() {
Thread t = new ExampleThread();
t.start();
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
synchronized(t) {
t.notify();
}
}
}
However, even this code may not work like you want. In a scenario where the main thread gets to the notify() part before the secondary thread had a chance to get to the wait() part (unlikely in your case, but still possible - you can observe it if you put Thread.sleep at the beginning of the secondary thread), the secondary thread will never be waken up. Therefore, the safest method would be something similar to this:
public class Main {
public class ExampleThread extends Thread {
public ExampleThread() {
System.out.println("ExampleThread's name is: " + this.getName());
}
#Override
public void run() {
synchronized (this) {
try {
notify();
wait();
} catch (InterruptedException e) {
}
}
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
}
}
public static void main(String[] args) {
new Main().go();
}
public void go() {
Thread t = new ExampleThread();
synchronized (t) {
t.start();
try {
t.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
for(int i = 1; i < 1000; i++) {
System.out.println(Thread.currentThread().getName());
System.out.println(i);
}
synchronized(t) {
t.notify();
}
}
}
In this example the output is completely deterministic. Here's what happens:
Main thread creates a new t object.
Main thread gets a lock on the t monitor.
Main thread starts the t thread.
(these can happen in any order)
Secondary thread starts, but since main thread still owns the t monitor, the secondary thread cannot proceed and must wait (because its first statement is synchronized (this), not because it happens to be the t object - all the locks, notifies and waits could as well be done on an object completely unrelated to any of the 2 threads with the same result.
Primary thread continues, gets to the t.wait() part and suspends its execution, releasing the t monitor that it synchronized on.
Secondary thread gains ownership of t monitor.
Secondary thread calls t.notify(), waking the main thread. The main thread cannot continue just yet though, since the secondary thread still holds ownership of the t monitor.
Secondary thread calls t.wait(), suspends its execution and releases the t monitor.
Primary thread can finally continue, since the t monitor is now available.
Primary thread gains ownership of the t monitor but releases it right away.
Primary thread does its number counting thing.
Primary thread again gains ownership of the t monitor.
Primary thread calls t.notify(), waking the secondary thread. The secondary thread cannot continue just yet, because the primary thread still holds the t monitor.
Primary thread releases the t monitor and terminates.
Secondary thread gains ownership of the t monitor, but releases it right away.
Secondary thread does its number counting thing and then terminates.
The entire application terminates.
As you can see, even in such a deceptively simple scenario there is a lot going on.
You are lucky that your program terminates at all.
When you call t.wait() your main threads stops and waits indefinitely on a notification.
It never gets it, but I believe is awaken by spurious wakeup when the secondary thread finishes. (Read here on what a spurious wakeup is).
ExampleThread doesn't wait() or notify(), and isn't synchronized on anything. So it will run whenever it can without any coordination with other threads.
The main thread is waiting for a notification which never comes (this notification should be sent by another thread). My guess is that when the ExampleThread dies, the main thread is woken "spuriously," and completes.
The thread that should wait for another to complete must perform the call to wait() inside a loop that checks for a condition:
class ExampleThread extends Thread {
private boolean ready = false;
synchronized void ready() {
ready = true;
notifyAll();
}
#Override
public void run() {
/* Wait to for readiness to be signaled. */
synchronized (this) {
while (!ready)
try {
wait();
} catch(InterruptedException ex) {
ex.printStackTrace();
return; /* Interruption means abort. */
}
}
/* Now do your work. */
...
Then in your main thread:
ExampleThread t = new ExampleThread();
t.start();
/* Do your work. */
...
/* Then signal the other thread. */
t.ready();
I just learned from sun's document that when i invoke thread.stop() method, the run() method will be terminated as the ThreadDeath error thrown out, and also release all the locks this thread holds, how to prove it?
I tried my test program, shown below:
public static void main(String[] args) {
final Object lock = new Object();
try {
Thread t = new Thread() {
public synchronized void run() {
try {
synchronized (lock) {
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++)
System.out.println("runing.." + i);
System.out
.println((System.currentTimeMillis() - start) / 1000);
}
} catch (Throwable ex) {
System.out.println("Caught in run: " + ex);
ex.printStackTrace();
}
}
};
t.start();
// Give t time to get going...
Thread.sleep(100);
t.stop(); // EXPECT COMPILER WARNING
} catch (Throwable t) {
System.out.println("Caught in main: " + t);
t.printStackTrace();
}
}
Only if i put an wait() in the run() method, then i can catch the ThreadDeath error, does anyone know the details of how jvm handle stop()?
public static void main(String[] args) {
final Object lock = new Object();
try {
Thread t = new Thread() {
public synchronized void run() {
try {
synchronized (lock) {
wait();
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++)
System.out.println("runing.." + i);
System.out
.println((System.currentTimeMillis() - start) / 1000);
}
} catch (Throwable ex) {
System.out.println("Caught in run: " + ex);
ex.printStackTrace();
}
}
};
t.start();
// Give t time to get going...
Thread.sleep(100);
t.stop(); // EXPECT COMPILER WARNING
} catch (Throwable t) {
System.out.println("Caught in main: " + t);
t.printStackTrace();
}
}
The simple answer is that the jvm has no reliable way to stop a thread. To stop or interrupt a thread, the target thread needs to cooperate by entering some interrupt-able state, such as sleep() or wait().
The Thread.stop() method has been deprecated for this reason (among others). See http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html for more details.
I do not think that I can explain better than Sun.
Here are the quotes from official Javadoc:
Deprecated. This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target threalink textd waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.
See here:
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html
that is because the thread executes before your current thread comes out of sleep and calls the t.stop.
The Thread.stop() doesn't stop a thread. Instead it call Thread.stop(new ThreadDeath()) which triggers the thread to throw this Error, which is silently ignored by default. i.e. if you throw any other Throwable the uncaughtException will print it to System.err. From ThreadGroup
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread \""
+ t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
}
There is nothing else special/magical about this error. Your thread will unwind in the same manner at it would if you threw new ThreadDeath(). For comparison, try
thread.stop(new RuntimeException());
The explanations about Thread.stop are pretty much right on. The proper way to build a cooperative runnable is as follows:
public class MyRunnable implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
public void run() {
// do stuff
if (stopped) {
// cleanup and return;
}
// do more stuff
if (stopped) {
// cleanup and return;
}
}
}
Runnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
r.stop();
t.join(); // if you want to wait for it to die.
OR
public class MyRunnable implements Runnable {
public void run() {
// do stuff
if (Thread.currentThread().isInterrupted()) {
// cleanup and return;
}
// do more stuff
if (Thread.currentThread().isInterrupted()) {
// cleanup and return;
}
}
}
Runnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
t.interrupt();
t.join(); // if you want to wait for it to die.
Note that in either case, you have strategic stop points in your code where you're checking to see if you should continue processing. The second approach has the advantage that interrupt aware operations like Thread.sleep and java.nio based I/O operations can be immediately interrupted and don't have to wait for your stop point. Instead they would throw an InterruptedException immediately (or in the case of NIO a ClosedByInterruptException). Note that standard java.io based I/O is not interrupt aware, and you'll have to wait for one of your coded stop points.
The real answer is that the stop method of class Thread calls the private stop1 method which is synchronized. As your implementation of the thread's run method is also synchronized the stop1 method cannot be entered until the run method is exited.