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
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.
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.
I have read the Java Concurrency in Practice on page 146, and I have coded the:
class RethroableTask implements Runnable{
private static final ScheduledExecutorService cancelExec =
Executors.newScheduledThreadPool(1);
private Throwable t;
public void run(){
try{
while(true){}
}catch(Throwable t){
this.t = t;
}
}
public static void main(String[] args){
RethroableTask task = new RethrowableTask();
final Thread taskThread = new Thread(task);
taskThread.start();
cancelExec.schedule(new Runnable(){
public void run(){
taskThread.interrupt();//i want taskThread can catch interruptedException
}
},1,TimeUnit.SECONDS);
}
}
I want taskThread to catch InterruptedException as Throwable, and really the taskThread isInterrupted is true,but taskThread never catches it. Why?
I substitute while(true){} with
try{
Thread.currentThread().sleep(1000);//a blocking method
}catch(InterruptedException e){
System.out.println("interruptedException");
Thread.currentThread().interrupt();
}
it come in catch
An InterruptedException is only thrown when a thread is waiting on a blocking method call at the moment of interruption.
In all other situations, a thread must check its own interrupted status. If you want to test the class you've written, call a blocking method in your while loop.
Unlike stopping, interruption is a cooperative mehanism: the InterruptedException must be explicitly thrown by some code after checking the interrupted flag of the current thread. This can be either a JDK method which declares to throw InterruptedException such as Thread.sleep, or your own code.
Instead of your empty loop, use
while (true) Thread.sleep(Integer.MAX_VALUE);
This will solve two problems at once:
it won't hog the CPU;
it will throw an InterruptedException when interrupted.
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.
Thread currentThread=Thread.currentThread();
public void run()
{
while(!shutdown)
{
try
{
System.out.println(currentThread.isAlive());
Thread.interrupted();
System.out.println(currentThread.isAlive());
if(currentThread.isAlive()==false)
{
shutdown=true;
}
}
catch(Exception e)
{
currentThread.interrupt();
}
}
}
});
thread.start();
The alternative to calling stop is to use interrupt to signal to the thread that you want it to finish what it's doing. (This assumes the thread you want to stop is well-behaved, if it ignores InterruptedExceptions by eating them immediately after they are thrown and doesn't check the interrupted status then you are back to using stop().)
Here's some code I wrote as an answer to a threading question here, it's an example of how thread interruption works:
public class HelloWorld {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
Thread.sleep(5000);
System.out.println("Hello World!");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
thread.start();
System.out.println("press enter to quit");
System.in.read();
thread.interrupt();
}
}
Some things to be aware of:
Interrupting causes sleep() and wait() to immediately throw, otherwise you are stuck waiting for the sleep time to pass.
Note that there is no need for a separate boolean flag.
The thread being stopped cooperates by checking the interrupted status and catching InterruptedExceptions outside the while loop (using it to exit the loop). Interruption is one place where it's ok to use an exception for flow control, that is the whole point of it.
Setting interrupt on the current thread in the catch block is technically best-practice but is overkill for this example, because there is nothing else that needs the interrupt flag set.
Some observations about the posted code:
The posted example is incomplete, but putting a reference to the current thread in an instance variable seems like a bad idea. It will get initialized to whatever thread is creating the object, not to the thread executing the run method. If the same Runnable instance is executed on more than one thread then the instance variable won't reflect the right thread most of the time.
The check for whether the thread is alive is necessarily always going to result in true (unless there's an error where the currentThread instance variable is referencing the wrong thread), Thread#isAlive is false only after the thread has finished executing, it doesn't return false just because it's been interrupted.
Calling Thread#interrupted will result in clearing the interrupt flag, and makes no sense here, especially since the return value is discarded. The point of calling Thread#interrupted is to test the state of the interrupted flag and then clear it, it's a convenience method used by things that throw InterruptedException.
Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():
Thread t = new Thread(new Runnable(){
#Override
public void run() {
while(!Thread.currentThread().isInterrupted()){
// do stuff
}
}});
t.start();
// Sleep a second, and then interrupt
try {
Thread.sleep(1000);
} catch (InterruptedException e) {}
t.interrupt();
Good way to do it would be to use a boolean flag to signal the thread.
class MyRunnable implements Runnable {
public volatile boolean stopThread = false;
public void run() {
while(!stopThread) {
// Thread code here
}
}
}
Create a MyRunnable instance called myrunnable, wrap it in a new Thread instance and start the instance. When you want to flag the thread to stop, set myrunnable.stopThread = true. This way, it doesn't get stopped in the middle of something, only where we expect it to get stopped.