after catching "InterruptedException", why "Thread.currentThread().isInterrupted()"'s value is false? - java

as the title.
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().isInterrupted()); //print false, who reset the interrupt?
}
}
});
thread.start();
TimeUnit.SECONDS.sleep(1);
thread.interrupt();
}
after catching "InterruptedException", why "Thread.currentThread().isInterrupted()"'s value is false?

From the Javadoc for Thread.sleep (called by TimeUnit.sleep):
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
I think the intention of isInterrupted() is to allow you to detect whether a thread has been interrupted before calling something which would throw InterruptedException. If you've caught InterruptedException, it's fair to assume that the thread has been interrupted...

Related

Should sleeping interrupted thread reinterrupt itself if it was awaken?

The thread is working until it is interrupted but it is sleeping from time to time:
public void run() {
while (!Thread.interrupted()) {
//A TASK HERE
try {
Thread.sleep((long) (500 + Math.random() * 100));
} catch (InterruptedException e) {
interrupt(); //it was interrupted while it was sleeping
}
}
}
The intention is to kill the thread by interrupting it. Can I reinterrupt itself like I did or I should set a flag stop = true within the exception clause?
Catch the interruption outside the loop:
public void run() {
try {
while (true) {
//A TASK HERE
Thread.sleep((long) (500 + Math.random() * 100));
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
Irrespective of where you catch the InterruptedException, it's a good idea to reinterrupt the current thread if you've not really handled it, and you can't simply throw the InterruptedException (e.g. because it's inside a method which doesn't declare that it throws InterruptedException or Exception or Throwable).
This allows callers of the run() method to know that execution was interrupted, so they can stop what they are doing too.
The main case where you may decide not to re-interrupt the thread is if you are writing some sort of threading framework (like Executors), where you reuse the previously-interrupted thread to do the next task.

Proper use of wait and notify methods in Java threading

I am new to Java multithreading. I created simple producer-consumer pattern using wait and notify but my producer is getting called only once in tbe starting.
public class ThreadApp {
public static void main(String[] args) throws InterruptedException {
ProducerConsumerWorldp = new ProducerConsumerWorld();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
p.producer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
p.consumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
class ProducerConsumerWorld{
public void producer() throws InterruptedException{
synchronized (this) {
while(true){
System.out.println("Producer thread started running");
wait();
System.out.println("Resumed Producing");
}
}
}
public void consumer() throws InterruptedException{
synchronized (this) {
while(true){
Thread.sleep(2000);
System.out.println("Consumer thread started running");
System.out.println("Press enter to consume all and start producing");
Scanner s = new Scanner(System.in);
s.nextLine();
notify();
Thread.sleep(2000);
System.out.println("consumed all");
}
}
}
}
I am creating separate threads for producer and consumer. Producer thread only gets called in the starting and then after it is never getting executed.
I tried two option to overcome this issue. first I put while condition outside of synchronized block second is given below.
class ProducerConsumerWorld{
public void producer() throws InterruptedException{
synchronized (this) {
while(true){
System.out.println("Producer thread started running");
notify();
wait();
System.out.println("Resumed Producing");
}
}
}
public void consumer() throws InterruptedException{
synchronized (this) {
while(true){
Thread.sleep(2000);
System.out.println("Consumer thread started running");
System.out.println("Press enter to consume all and start producing");
Scanner s = new Scanner(System.in);
s.nextLine();
notify();
Thread.sleep(2000);
System.out.println("consumed all");
wait();
}
}
}
}
Both works great. Which one the of the appropriate solution to use ? I am still unable to figure out why the code I put in question is not working properly.
I am still unable to figure out why the code I put in question is not working properly
The wait() in producer() releases the monitor which allows consumer() to enter its synchronized block. Then the wait() in producer() starts waiting till consumer() calls notify() and releases the monitor (i.e. exits its synchronized block). You never exit synchronized in consumer() therefore the wait() in producer() is blocked forever
I am still unable to figure out why the code I put in question is not
working properly
I've managed to fix your code, and I've attached below the fixed code snippet.
I've introduced a boolean instance variable named isConsumed for the ProducerConsumerWorld. In doing so, what essentially happens is that after Producer Thread produces, he updates the state of isConsumed to false, since he has produced something which is yet to be consumed. Afterwards, the producer notifies the the Consumer thread, that Producer has finished producing. Next, it invokes wait() on the ProducerConsumerWorld which releases Producer's lock on ProducerConsumerWorld. Then, it waits for the lock on ProducerConsumerWorld.
Meanwhile, the Consumer Thead acquires the lock on ProducerConsumerWorld, which allows it to enter the consumer method, where it checks if there is produce yet to be consumed. If so, it consumes and updates the isConsumed variable to true, and notifies the produce has been consumed. Then the consumer proceeds to releases its lock on ProducerConsumerWorld by calling wait(), and waits to reacquire the lock on ProducerConsumerWorld after Producer has consumed.
Note:
Calling notify() doesn't release a lock until the thread moves out of the synchronized block, or wait() is called, thus releasing the lock.
Source: Oracle's OCA/OCP Java SE 7 Study Guide Page 760
Code:
import java.util.Scanner;
public class ThreadApp {
public static void main(String[] args) throws InterruptedException {
ProducerConsumerWorld p = new ProducerConsumerWorld();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
p.producer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
p.consumer();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
}
class ProducerConsumerWorld{
boolean consumed = false;
public void producer() throws InterruptedException{
System.out.println("Producer thread started running");
synchronized (this) {
while(this.consumed == true){ // Consumer has consumed and is waiting for produce
System.out.println("Resumed Producing");
this.consumed = false;
notify();
wait();
}
}
}
public void consumer() throws InterruptedException{
synchronized (this) {
while(this.consumed == false){
Thread.sleep(2000);
System.out.println("Consumer thread started running");
System.out.println("Press enter to consume all and start producing");
Scanner s = new Scanner(System.in);
s.nextLine();
this.consumed = true;
System.out.println("consumed all");
notify();
wait();
}
}
}
}
This gives me an output like,

Wait And Notify IllegalMonitorStateException Anonymous Class

According to How to use wait and notify in Java? I have to synchronized on the same object to call notify.
I have synchronized on the same haveCoffee object. Why I am getting IllegalMonitorStateException when I call the notify method ?
I am Sleeping
Exception in thread "Thread-1" java.lang.IllegalMonitorStateException
at java.lang.Object.notify(Native Method)
at com.example.concurrent.basic.WaitAndNotify$2.run(WaitAndNotify.java:42)
in the following code:
public class WaitAndNotify {
public static void main(String[] args) {
Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
On the first Thread, you call wait on an object while having its monitor (the object being this haveCoffee).
However, on the second thread, you call notify() on me, while having the monitor of haveCoffee.
This should work:
public class WaitAndNotify {
public static void main(String[] args) {
final Thread haveCoffee = new Thread() {
public void run() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.print("I am awake and ready to have coffee");
}
}
};
Thread me = new Thread() {
public void run() {
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
haveCoffee.start();
me.start();
}
}
From oracle documentation page,
public class IllegalMonitorStateException
extends RuntimeException
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.
Whenever you get this exception, just go through your code and check wait() and notify() calls and the object on which these calls have been invoked. You can easily figure out what went wrong.
EDIT:
wait() or notify() calls have to be invoked on object once you get monitor on that object.
You should be calling
haveCoffee.notify()
instead of just
notify().
If you invoke just notify() it calls the notify() method on the this object which is the second thread me where as you have synchronized on haveCoffee thread and that is the reason for exception you are seeing.
So the code in thread2 me should looks like:
synchronized (haveCoffee) {
try {
System.out.print("I am Sleeping");
Thread.sleep(4000);
haveCoffee.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}

Can't stop thread in Java

I'm trying to create a thread and then interrupt it. But it doesn't stop and cause exception. Can anybody explain what am I doing wrong? Thanks.
public class Test {
public static void main(String[] args) throws InterruptedException {
//Add your code here - добавь код тут
TestThread test = new TestThread();
test.start();
Thread.sleep(5000);
test.interrupt();
}
public static class TestThread extends Thread {
public void run() {
while (!this.isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
According to javadocs:
A thread interruption ignored because a thread was not alive at the
time of the interrupt will be reflected by this method returning
false.
Since you sleep the thread for 1000ms, when you call test.interrupt(), thread is asleep, almost all the times. So InterruptedException will be thrown. Therefore you should exit the loop at the catch clause.
Include a break when you catch InterruptedException to exit while loop.
while (!this.isInterrupted()) {
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
break;
}
}
The internal flag gets resetted after calling interrupt.
You have to call it again in your catch of the thread.
The topic was also covered in the Java Specialists Newsletter
In my example, after I caught the InterruptedException, I used
Thread.currentThread().interrupt() to immediately interrupted the
thread again. Why is this necessary? When the exception is thrown, the
interrupted flag is cleared, so if you have nested loops, you will
cause trouble in the outer loops
Something like this should work:
try {
Thread.sleep(1000);
System.out.println("I did the Thread");
} catch (InterruptedException e) {
this.interrupt();
// No need for break
}
This makes sure that the rest of the code is executed.

Need sample program to throw InterruptedException

I am going through the kathy sierra SCJP 1.5 Chapter 9(threads) and there it is mentioned as:
Notice that the sleep() method can throw a checked InterruptedException
(you'll usually know if that is a possibility, since another thread has to explicitly do
the interrupting), so you must acknowledge the exception with a handle or declare
I just need a sample program to know when it happens (which i can run on my machine)?
I googled but could not find any sample code to test this functionality..
Thanks in Advance
Here's an example:
public class Test
{
public static void main (String[] args)
{
final Thread mainThread = Thread.currentThread();
Thread interruptingThread = new Thread(new Runnable() {
#Override public void run() {
// Let the main thread start to sleep
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
mainThread.interrupt();
}
});
interruptingThread.start();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
System.out.println("I was interrupted!");
}
}
}
To walk through it:
Set up a new thread which will sleep for a short time, then interrupt the main thread
Start that new thread
Sleep for a long-ish time (in the main thread)
Print out a diagnostic method when we're interrupted (again, in the main thread)
The sleep in the main thread isn't strictly necessary, but it means that the main thread does get to really start sleeping before it's interrupted.
public class SleepTest1 extends Thread {
#Override
public void run() {
try {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
Thread.currentThread().interrupt();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
SleepTest1 st1 = new SleepTest1();
st1.start();
}
}

Categories

Resources