This should be a simple take for any Java Master. Me being a newbie just wanted to confirm one thing.
I have a class implementing Runnable and like many such classes its run() method has an infinite loop. I want to do some task and then sleep for a min and come back again.
What happens if an Interrupted Exception is encountered while a thread is sleeping?
What I think would happen is the thread being suspended and now the infinite loop is of no help to keep the thread runnning. I'd like to confirm if my understanding is correct or not.
If this is what happens, What would be a possible solution to start up the thread up again.?
Wrong.
An InterruptedException would just terminate the sleep() call and throw an exception.
As long as you handle the exception appropriately, your thread will continue running.
Your understanding is mostly correct - When your thread is sleeping , if it gets interrupted , this will cause an InterruptedException to be thrown - your code in run() will have to catch it and do what it wants to do. The thread itself will not be suspended - because active execution continues on this thread.
You may want to continue the execution of the thread after you handle the InterruptedException in your catch block.
The thread will not be suspended.
If you catch the InterruptedException, execution will continue in your exception handler.
If you do not catch the InterruptedException, the thread will terminate.
InterruptedExceptions don't just happen. Some exceptions, like IOExceptions, happen unpredictably due to inherent flakiness of the medium, but that is not the case for interruptions.
Interruption is a deliberate signal to a thread, usually sent by the application while it is shutting down, that it should finish up what it's doing and stop running. If the thread getting interrupted happens to be waiting or sleeping at the time, then the thread gets woken up and an InterruptedException gets thrown from the wait or sleep method.
Useful libraries like java.util.concurrent and guava use interrupts for thread cancellation. If you try to use them for something else then you can't use those libraries.
Related
I have seen many times in my code that I get an Interrupted Exception. How do I fix it?
Example:
for (int i = 0; i < readLimit; i++) {
if (fileName.exists())
return readFile(fileName);
Thread.sleep(1000); // Here is where I get the error
}
}
Since I don't know how much you know about Java, how java works exactly and what's concurrency, I'll try to explain as much as possible with nearly no background information needed.
At first we're going to take a look at Oracle's documentation of the InterruptedException.
Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is interrupted, either before or during the activity. [...]
What does this mean?
Before answering this question you have to rudimentary understand how a Thread works.
A thread is originally just a piece of code that can be managed seperately from other threads. It can run at the same time (see concurrency), run scheduled, etc.
Example
If you start a normal java program the main() method is created in an own thread 1. Everything you do will be executed in this thread. Every class you create, every method you call and basically everything that originated from main().
But if you create a Thread, it runs in an own thread 2. Everything you do in the run() method will be executed in thread 2.
What happens if you create a new Thread?
The join() method is called.
The join() method starts the thread and run() is being executed.
There's not only the join() method with no parameters but also a join(long millis) with a parameter.
When and why is it thrown?
As Rahul Iyer already said there's a variety of reasons. I'm picking some of them to get you a feeling when they're called.
Timeout
The InterruptedException can be indeed thrown when a timeout was exceeded. This happens when the join(long millis) is called. The parameter specifies that the thread can run for the given amount of milliseconds. When the thread exceeds this timeout it is interrupted. source (from line 769 to line 822).
OS is stopping the thread
Maybe the Operating System (Windows, Linux, Android, etc.) decided to stop the program. Why? To free resources, your program was mistaken as a virus, hardware is shutting down, the user manually closed it, etc.
An InterruptedException is thrown in the Thread
For example you're connected to the internet and you're reading something and the internet disconnects suddenly.
interrupt() is called
As already mentioned, an InterruptedException is also thrown, when you call the interrupt() on any Thread (quite logical).
How to handle it?
You can/should handle it like every other exception. Wrap it in a try and catch, declare that the method throws it, log it, etc.
This may be the best resource for you: Handling InterruptedException in Java.
From the docs: https://docs.oracle.com/javase/7/docs/api/java/lang/InterruptedException.html
public class InterruptedException extends Exception
Thrown when a thread is waiting, sleeping, or otherwise occupied, and the thread is
interrupted, either before or during the activity. Occasionally a
method may wish to test whether the current thread has been
interrupted, and if so, to immediately throw this exception. The
following code can be used to achieve this effect:
if (Thread.interrupted()) // Clears interrupted status!
throw new InterruptedException();
You can follow oracles tutorial here:
https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
The way to fix it is probably to surround the code that causes it with a Try-Catch block and handle the exception. For example (from Oracles tutorial):
for (int i = 0; i < importantInfo.length; i++) {
// Pause for 4 seconds
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
// Print a message
System.out.println(importantInfo[i]);
}
There are more examples in the above link on how to handle different scenarios.
Shortly, InterruptedException is usually thrown when a thread or some other action is interrupted. It does not matter if the thread was doing something or sleeping, you can programmatically do this by calling interrupt() or other methods on and "occupied" thread, who is for sleeping.
How the second loop actually interrupts the sleeping main thread, and first does not??
My understanding is after Thread.sleep(3000), the code Thread.currentThread().interrupt() will be executed after 3 seconds.
Can anyone explain how it actually works
for (int i = 0; i < 2; i++) {
try {
System.out.println("loop : " + i);
Thread.sleep(3000);
System.out.println("Woke up");
Thread.currentThread().interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
loop : 0
Woke up
loop : 1
java.lang.InterruptedException: sleep interrupted
exception loop:1
at java.base/java.lang.Thread.sleep(Native Method)
at multithreadings.Mainclass.main(Mainclass.java:13)
Interruption is a polite request to stop: a Thread is under no obligation to stop.
It's like the Robin Williams joke about what police in the UK say when you commit a crime:
Stop! Or I'll say stop again!
Also, interrupting a thread doesn't cause an InterruptedException to be thrown: it merely sets a flag on the thread. If something (like Thread.sleep) checks this flag, and finds that it is set, it may then throw an InterruptedException; but the flag and exception are two orthogonal ways of indicating interruption.
As such:
On the first execution, you sleep for 3 seconds, then set the interrupted flag, and the loop body finishes normally.
On the second execution, you ask to sleep for 3 seconds, but Thread.sleep detects the interrupted flag, and throws the exception.
There is a single thread involved in the code you posted. This thread executes a loop. At the first iteration, the thread interrupts itself. Interrupting doesn't mean "stop executing immediately". It means: "please, I would like you to stop running when you can".
A thread that wants to respect interruption requests can do it in two ways:
It regularly checks if it has been interrupted, and if it's the case, then it stops executing (by breaking out of a loop or returning, for example)
It calls a blocking method such as sleep(), which will throw an InterruptedException if the thread has been interrupted or is being interrupted.
What happens is the second case. A request for interruption is done in the first iteration, after the call to sleep(). The thread continues running, and at the second iteration, it calls sleep(), which throws en InterruptedException because the thread has been interrupted before.
In Java, one thread cannot stop the other thread. A thread can only request the other thread to stop. The request is made in the form of an interruption. Calling the interrupt() method on an instance of a Thread sets the interrupt status state as true on the instance.
All blocking methods respond to interruption by throwing InterruptedException once the interrupt status is set to true. , if you want to check more in detail, please read the below article. See how Thread Interruption works in Java.
Read the documentation, i.e. the javadoc of interrupt():
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, ...
If this thread is blocked ...
If this thread is blocked ...
If this thread is blocked ...
If none of the previous conditions hold then this thread's interrupt status will be set.
and sleep(long millis):
Throws InterruptedException if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
Since the thread has already interrupted itself on the second iteration of the loop, thereby setting it's own interrupted status, the sleep(...) method is immediately interrupted.
I am reading Interrupts from Oracle Docs. I am unable to figure out the following
part. It states that
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. For example:
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
I am scratching my head to understand, what does it mean by What if a thread goes a long
time without invoking a method that throws InterruptedException? Secondly, what is the usage
of Thread.interrupted(), it is a way, that thread can send a interrupt to itself? Whats the
practical usage of this scenario? Thanks.
This is a technique to keep the thread available for interruption.
Thread.interrupted() : checks whether present thread (itself) was interrupted by some other thread and clears the interrupted status flag. So it asks itself whether I was interrupted by someone to exit from what I was doing while I was performing a BIG BIG task and not listening to someone.
Imagine what would have happened if that thing was not done.
Suppose one iteration of heavyCrunch() takes 1 min worth of time. So n iterations will take n minutes.
Now suppose after starting the program you decide that you want to exit the program and terminate the program gracefully. So you interrupt the thread that is doing the heavy crunch.
BUT the thread is unknown of the fact that you have interrupted it as it is not checking for the interrupt status. So the program will not end until N Minutes have not completed and you will have to wait for long time.
So to gracefully terminate the thread, it should always keep checking the interrupt status to respond if someone else has requested interruption.
If you interrupt the thread running this code
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
}
it will only set interrupted status in the thread but it will not stop it
Thread.interrupted tests if interrupted status is set (and clears it) so by adding
if (Thread.interrupted()) {
return;
}
to the loop you make the code interruptible
Besides the fact that the phrase
What if a thread goes a long time without invoking a method that throws InterruptedException?
is deeply unclear, i suppose they mean the following:
Usually, if you have a thread that does some work in a while(true) loop, that is, a thread that does not terminate for a long time, you will probably place ANY function that throws InterruptedException in that thread (i.e. Thread.sleep(), a socket read, or anything!). This way, when your thread will be noticed an Interruption, one of those functions will catch it and you will be able to QUIT what you are doing in the thread (the thread does not just magically terminate itself).
Here comes what the phrase wanted to say:
WHAT IF YOU DO NOT WANT/HAVE to use these functions? Then you should use Thread.interrupted() to check whether you should QUIT doing what the thread is doing in the same way you would do if you catched an InterruptedException.
I hope this was clearer than the doc...
You can use interrupted() stop nicely any long running thread by intrrup thread somewhere and check the condition by Thread.interrupted() and based on this come out of run method.
Let say you one thread is blocked on some monitor and somewhere else that thread got interrupted which inturn will throw InterruptedExceptionand can come out of block state with interrupted status true.
I think interrupt is the best way to achieve stop long running task because an interrupt will unblock some blocking IO and synchronization requests. A bespoke solution cannot do this.
May help you.
interrupt() sets from outside a flag in the object that can then be queried periodically by Interrupted() in the run() method.
I am scratching my head to understand, what does it mean by What if a thread goes a long time without invoking a method that throws InterruptedException?
A: If other thread call the interupt() method of this thread, and 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. Otherwise, just set the interrupt status.
Secondly, what is the usage of Thread.interrupted(), it is a way, that thread can send an interrupt to itself? What's the practical usage of this scenario?
A: Thread.interrupted() is use to detect current thread's interrupt status, return true if it's set and then clear the status. You check this in order to respond to other thread's interrupt call, such as throw an InterruptedException and exit the thread or just exit.
While going through the javadoc for the notifyAll() method under Object class came through the following lines:
If the current thread is interrupted by any thread before or while it is waiting, then an
InterruptedException is thrown. This exception is not thrown until the lock status of this object has been restored as described above.
The point is:
the current thread is interrupted while it is waiting
What does this means? Can a thread be interrupted while it is waiting?
If yes, why? What is the use of it?
The meaning of "thread getting interrupted" in Java means that the thread's interrupted flag has been set, nothing more. However, most methods of the JDK which make the thread wait will immediately find out about this and exit the wait state, throwing an InterruptedException. Such is the case with the methods you have been reading about.
A thread can be interrupted while waiting if another thread calls:
waitingThread.interrupt();
This can happen if you do it yourself of course but also if you use a framework to manage your threads, typically an executor service, and call some of the methods that interrupt the underlying threads (e.g. shutdownNow or if you call future.cancel(true); on the Future returned by the submit method).
The interruption mechanism is how Java enables one thread to tell another one to stop what it is doing and is therefore extremely useful.
I'm relatively new to Threading in Java and I've noticed that everytime I use Thread.sleep() I have to catch InterrupetdException.
What kind of behaviour causes this, and in simple applications where I have a monitor thread can I just Ignore the exception?
It happens when something calls interrupt() on the thread. This article by Brian Goetz explains the interruption mechanism and how you should handle InterruptedExceptions:
"The most common response to InterruptedException is to swallow it -- catch it and do nothing (or perhaps log it, which isn't any better) -- as we'll see later in Listing 4. Unfortunately, this approach throws away important information about the fact that an interrupt occurred, which could compromise the application's ability to cancel activities or shut down in a timely manner."
"If you catch InterruptedException but cannot rethrow it, you should preserve evidence that the interruption occurred [...]. This task is accomplished by calling interrupt() to "reinterrupt" the current thread."
As others have said, it is caused by some other thread calling interrupt() on the Thread object that is sleeping.
What this means in plain english, is that some other thread has decided to cancel the sleeping thread. The try/catch block is there so you can gracefully handle the cancellation of the thread, and safely clean up any resources, or shut down whatever operation it was doing correctly.
If you don't actually need to do any of that, then yes, you still need an empty catch block. But that's Java for you...
Some advices from Java Concurrency in Practice:
Propagate the exception (possibly after some task-specific cleanup), making your method an interruptible blocking method, too; or
Restore the interruption status so that code higher up on the call stack can deal with it.
Only code that implements a thread's interruption policy may swallow an interruption request. General-purpose task and library code should never swallow interruption requests.
The primary case is when someone calls Thread.interrupt() on your thread.
It may be safer to throw a RuntimeException if it happens when you're really not expecting it, but for very simple cases you can probably ignore it.
From the javadocs:
Class InterruptedException
Thrown when a thread is waiting,
sleeping, or otherwise paused for a
long time and another thread
interrupts it using the interrupt
method in class Thread.
Hope that answers your question.
Well if some other Thread calls thread.interupt(), while the thread is sleeping, you'll get the Exception. And yes, you can probably just put try..catch arround the sleep() and ignore it ;)
InterruptedException is a checked exception so unfortunately you cannot just ignore it. In most simple cases you do not have to do anything in the catch clause because you are sure that it will not happen.
From the API
Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread.