Here says that sleep() throws InterruptedException when another thread interrupts this thread while sleep is active. So why I have an infinity loop there but don't InterruptedException?
public class Test
{
public static void main(String[] args) throws InterruptedException
{
Test2 t2 = new Test2();
t2.start();
t2.sleep(1_000);
t2.interrupt();
}
}
class Test2 extends Thread
{
#Override
public void run()
{
while (true) {}
}
}
(At least) four problems:
Firstly, you're not actually making t2 sleep. Thread.sleep is a static method, so t2.sleep(1_000) is actually effectively Thread.sleep(1_000), so you're just making the current thread sleep.
(Can you imagine the mayhem you could cause if you were allowed to make other threads sleep arbitrarily...?)
Secondly, you're not actually checking for interruption in Test2. So, when you do interrupt it, nothing is listening for the interruption, so nothing will happen.
If you want to check for interruption, you could do something like
while (!interrupted()) {}
but even this won't throw an InterruptedException: the loop will just stop executing.
Thirdly, Test2 did throw an InterruptedException in its run() method, it would have to be handled within that method. InterruptedException is a checked exception, so you can't add throws InterruptedException to its signature, because run() doesn't declare that it throws any checked exceptions. As such, it would never "escape" the method.
Fourthly, even if you did manage to get the InterruptedException to escape the Thread.run() method (there are devious and vile ways to do this), that doesn't mean it would be catchable inside the main thread. The exception would be handled by the uncaught exception handler, and the main thread would continue none-the-wiser.
Related
Code as below:
import java.util.concurrent.TimeUnit;
public class Test {
public static void main(String[] args) throws InterruptedException {
Thread thread = new Thread(() -> {
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
thread.start();
TimeUnit.SECONDS.sleep(1);
thread.interrupt();
System.out.println(thread.isInterrupted());
}
}
Sometimes System.out.println(thread.isInterrupted()); prints true while sometimes prints false !
So how can the code higher up the call stack see that an interrupt was issued as described in JCIP 5.4?
That's the way to go, but your code faces a race condition. Your main thread executes thread.isInterrupted() immediately after calling thread.interrupt().
The documentation states that
If this thread is blocked in an invocation of [...] or sleep(long, int) methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
Give thread thread a fair chance to catch the exception and to set the interrupt status, that is join the thread or wait a moment, at least.
If you execute the following code, you will see the thread is interrupted, however, Thread.interrupted() will return false
public class Test {
public static void main(String args[]) {
Thread t = new Thread() {
public void run() {
try {
synchronized (this) {
wait();
}
} catch (Exception e) {
e.printStackTrace();
System.out.println(Thread.interrupted());
}
}
};
t.start();
t.interrupt();
for (;;) {
}
}
}
Please help me understand why it is false, Instead it should be true
The JavaDocs are a wonderful thing...
Throws:
InterruptedException - if any thread
interrupted the current thread before or while the current thread was
waiting. The interrupted status of the current thread is cleared when
this exception is thrown.
When you call t.interrupt(), the wait() method throws an InterruptedException, yes, but only because internally it is periodically checking for interruptions by means of calling Thread.interrupted().
If you check the API for this last method, you can read:
public static boolean interrupted()
Tests whether the current thread has been interrupted. The interrupted status of the thread is cleared by this method. In other words, if this method were to be called twice in succession, the second call would return false (unless the current thread were interrupted again, after the first call had cleared its interrupted status and before the second call had examined it).
Which is exactly what is happening to you.
This is the reason why some articles like this one from IBM DeveloperWorks recommend to reset the interrupted flag every time we catch InterruptedException but don't plan on doing anything about the interruption itself:
When a blocking method detects interruption and throws InterruptedException, it clears the interrupted status. If you catch InterruptedException but cannot rethrow it, you should preserve evidence that the interruption occurred so that code higher up on the call stack can learn of the interruption and respond to it if it wants to. This task is accomplished by calling interrupt() to "reinterrupt" the current thread.
To get this code to compile, I can either:
Put my call to Thread.sleep() in a try/catch block, or
Have printAll() declare that it can throw an InterruptedException.
Why do I have to do this?
class Test {
public static void main( String[] args ) {
printAll( args );
}
public static void printAll( String[] line ) {
System.out.println( lines[ i ] );
Thread.currentThread().sleep( 1000 ):
}
}
(Sample code from Kathy Sierra's SCJP book.)
I know that the exception which Thread.sleep() throws is a checked exception, so I have to handle it, but in what situation does Thread.sleep() need to throw this exception?
If a method is declared in a way that it can throw checked exceptions (Exceptions that are not subclasses of RuntimeException), the code that calls it must call it in a try-catch block or the caller method must declare to throw it.
Thread.sleep() is declared like this:
public static void sleep(long millis) throws InterruptedException;
It may throw InterruptedException which directly extends java.lang.Exception so you have to catch it or declare to throw it.
And why is Thread.sleep() declared this way? Because if a Thread is sleeping, the thread may be interrupted e.g. with Thread.interrupt() by another thread in which case the sleeping thread (the sleep() method) will throw an instance of this InterruptedException.
Example:
Thread t = new Thread() {
#Override
public void run() {
try {
System.out.println("Sleeping...");
Thread.sleep(10000);
System.out.println("Done sleeping, no interrupt.");
} catch (InterruptedException e) {
System.out.println("I was interrupted!");
e.printStackTrace();
}
}
};
t.start(); // Start another thread: t
t.interrupt(); // Main thread interrupts t, so the Thread.sleep() call
// inside t's run() method will throw an InterruptedException!
Output:
Sleeping...
I was interrupted!
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at Main$1.run(Main.java:13)
One Thread can communicate with and interact with another Thread, and one way that it can do it is by interrupting it: if t is another Thread, you can call t.interrupt() to ask it politely to stop what it's currently doing. This is in particular something you might want to do if t is sleeping: you might want to wake it up. What it does is to cause an InterruptedException in t's Thread.sleep() method, so that it can catch it and respond. Because of this, any time you use Thread.sleep() to make the current thread go to sleep, you have to deal with the possibility of an InterruptedException in case another thread decides to wake it up.
In your case, you've only got one Thread, so you know that there can't be an InterruptedException from elsewhere in your code. But it's a not uncommon thing to want to do in multi-threaded code.
class Demo extends Thread{
public void run() {
for (int i = 0; i <10; i++) {
system.out.println("hello Ziyad");
thread.sleep(1000);
}} }
public class Threddemo{
public static void main(string[] args) throws interruptedexception {
Demo t=new Demo();
Demo t2=new Demo();
t.start();
t2.start();
}}
Suppose We have two Thread t and t2 and t is executing while executing, t2 came and t2 is also start executing but t is not finish yet
there the thread get interrupted and you lose your data.In above example t thread is running and when in spleeping mode, and there t2 came
and start executing suddenly t get up but t2 is running this is chance of interruptedexception and data lose to avoid this we use interruptedexception
I do not understand why the thread does not throw an InterruptedException when interrupted itself.
I'm trying with following snippet:
public class InterruptTest {
public static void main(String[] args) {
MyThread t = new MyThread();
t.start();
try {
t.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
#Override
public void run() {
Thread.currentThread().interrupt();
}
} }
In the API docs it says on the interrupt() method:
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 Thread.join(), Thread.join(long), Thread.join(long, int), Thread.sleep(long), or Thread.sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
I know this is an old question, but I think the answers above are actually not quite correct. (except #Skylion's, which doesn't really address the question...) :)
Thread.interrupt() does not throw any exceptions by itself. It does two things: First it simply sets an internal interrupted-flag and then it checks if the thread that it was called on is currently blocking on an activity like wait(), sleep(), or join(). If it finds one, then it wakes up that method and causes that method to throw the exception inside the thread it was called on (not from).
In the case where you call interrupt() from the thread itself, that thread obviously can't itself be currently blocking on one of those calls as it is currently executing your interrupt() call. So, only the internal interrupted-flag is set and no exception is thrown at all.
The next time you call one of the blocking methods (like sleep() in #OldCurmudgeon's example) from that thread, that method will notice the interrupted-flag and throw the InterruptedException.
If you don't ever call any of those methods, your thread will simply continue running until it terminates some other way and will never throw an InterruptedException. This is true even if you call interrupt() from a different thread.
So, to notice that your thread has been interrupted, you either need to frequently use one of the blocking methods that throws an InterruptedException and then quit when you receive one of those exceptions, or you need to frequently call Thread.interrupted() to check the internal interrupted-flag yourself and quit if it ever returns true. But you are also free to simply ignore the exception and the result from Thread.interrupted() completely and keep the thread running. So, interrupt() might be a little bit ambiguously named. It doesn't necessarily "interrupt" (as in "terminate") the Thread at all, it simply sends a signal to the thread that the thread can handle or ignore as it pleases. Much like a hardware interrupt signal on a CPU (which is probably where the name comes from).
To have the exception be thrown by the join() method in your main thread, you need to call interrupt() on that thread, rather than on MyThread, like so:
public static void main(String[] args) {
MyThread t = new MyThread();
t.setDaemon(true); // Quit when main thread is done
t.start();
try {
t.join();
} catch (InterruptedException ex) {
System.out.println("Now it works:");
ex.printStackTrace();
}
}
private static class MyThread extends Thread {
private final Thread parentThread;
public MyThread() {
parentThread = Thread.currentThread();
}
#Override
public void run() {
parentThread.interrupt(); // Call on main thread!!!
while (true); // Keep thread running (see comments)
}
}
See #markus-a's answer for what should have been the accepted answer here.
(Mine should be deleted, but I can't do that while it's accepted).
Exceptions are always thrown on their own thread. You have two different threads: your main thread and the one you created. There's no way the exception thrown in MyThread can be caught in the main one.
Why interrupt the thread at all? Just use
return;
You're just being too quick - try this:
private static class MyThread extends Thread {
#Override
public void run() {
try {
Thread.currentThread().interrupt();
Thread.sleep(5000);
} catch (InterruptedException ex) {
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, "Oops", ex);
}
}
}
I get:
Oct 04, 2013 12:43:46 AM test.Test$MyThread run
SEVERE: Oops
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at test.Test$MyThread.run(Test.java:36)
note that you cannot propagate the exception out of the run method because run does not throw any exceptions.
Is it sufficient to wrap contents of run method inside a while loop that checks if THread is interrupted for making any Thread interruptable
public void run () {
while (!Thread.interrupted()) {
do something.
}
}
How does a thread support its own interruption? This depends on what
it's currently doing. If the thread is frequently invoking methods
that throw InterruptedException, it simply returns from the run method
after it catches that exception.
Reference documentation
For a example if your thread goes for sleep bettween work then it is better to catch InterruptedException.
public void run(){
while(true)
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// We've been interrupted: no more messages.
return;
}
}
If your thread runs for long time you can check periodically invoke Thread.interrupted, which returns true if an interrupt has been received.
interrupted() is static method to check the current thread is interrupted or not. isInterrupted() is an instance to check the Thread objects called on.
For Present Thread use
if(!(Thread.interrupted())){//do something}
When Thread object called use if(myThread.isInterrupted()){//do something
}