4

Assume that I have the following code:

while(!Thread.currentThread().isInterrupted()){  
    //do something   
    Thread.sleep(5000);  
}

Now Thread.sleep throws `InterruptedException so it should be like this:

while(!Thread.currentThread().isInterrupted()){  
   //do something   
   try{  
     Thread.sleep(5000);    
   } catch(InterruptedException e){  

   }
}

If I hit the catch will the while loop continue or do I need to do Thread.currentThread().interrupt()? If I do call this method, won't that also cause an InterruptedException? Otherwise how I got the exception in the first place?

Also if I have:

while (!Thread.currentThread().isInterrupted()){  
   //do something   
   callMethod();  
}  

private void callMethod(){  
   //do something  
   try {  
     Thread.sleep(5000);    
   } catch(InterruptedException e){  

   }
}

again will my while loop break?

Gray
  • 115,027
  • 24
  • 293
  • 354
Jim
  • 18,826
  • 34
  • 135
  • 254

3 Answers3

2

Actually your question is more about try - catch - finally than about multithreading.

1) If sleep throws an Exception, the catch block will execute and then the while loop continues.

2) You do the exact same thing as in 1)

To leave the while loop, do:

try{  
   while(!Thread.currentThread.isInterrupted){  
       //do something   
       Thread.sleep(5000);    
   }  
}
catch(InterruptedException e){  

}

In that case, if an Exception is thrown, the while loop is left and the catch block is executed.

Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
  • +1: however I prefer to catch Exceptions inside the loop and then break or continue explicitly. – BigMike Feb 19 '13 at 09:08
  • @BigMike Yes, that approach is completely in line with the Java maxim "More code means better code". – Marko Topolnik Feb 19 '13 at 09:20
  • @MarkoTopolnik it's just that I don't want to use a catch block to control my program flow, if I need to exit from a loop, I want to be the one stating that with an explicit break, and that justfor the sake of who'll inherit my code tomorrow... – BigMike Feb 19 '13 at 09:24
  • 2
    @BigMike In other words, you'd prefer a language that doesn't have the exceptions mechanism. Exceptions control the flow whether you like it or not; you just make them control the flow in a way that involves more code. – Marko Topolnik Feb 19 '13 at 09:26
  • @MarkoTopolnik maybe you're right, I guess as usual it depends on personal taste and scenarios. Btw, I honestly hate java, still in love with good old C ;) – BigMike Feb 19 '13 at 09:30
  • @BigMike Exceptions are often a blessing as well---what if an interrupt signal needs to break out of a 10-level deep call stack? You'd need **a lot** of boilerplate code to handle that without exceptions and the end result would in no way be more comprehensible or maintainable. – Marko Topolnik Feb 19 '13 at 09:33
  • @Vakimshaar:So in the second case I should do:`Thread.currentThread.interrupt()` so that when `callMethod()` returns the `while` loop breaks? – Jim Feb 19 '13 at 09:47
  • @Jim In your 2nd case, you should place the ``try - catch`` block around the ``callMethod()`` – Jean Logeart Feb 19 '13 at 13:36
  • @Vakimshaar:Why?If I do the `try-catch` inside the `callMethod()` and in the `catch` I do `Thread.currentThread.interrupt()` won't the loop break? – Jim Feb 20 '13 at 07:31
2

Calling interrupt on a thread does not in itself throw an exception. Sleeping or waiting while the interrupt flag is set is what causes InterruptedException to be thrown.

It is totally predictable what can throw InterruptedException, so that the thread being interrupted has control and it can choose how to respond. It's a checked exception so it's evident what throws it. It is not like ThreadDeath, which can be thrown anywhere.

When an InterruptedException is thrown the thread's interrupted status is reset. If you want to restore the thread's interrupted status, because you want to check the flag later and have it be true, call Thread.currentThread().interrupt() in order to set it.

Nothing out of the ordinary happens during interruption to change how instructions get processed. So if you choose to catch the InterruptedException in a loop and check the flag to get out, you will need to reset the flag:

while(!Thread.currentThread().isInterrupted()){  
   //do something   
   try{  
     Thread.sleep(5000);    
   } catch(InterruptedException e){  
        Thread.currentThread().interrupt();
   }
}

Alternatively you can use the InterruptedException to get out of the loop:

try {
    while (!Thread.currentThread().isInterrupted()) {
        // do something
        Thread.sleep(5000);
    }
} catch (InterruptedException e) {
    // flag value is not used here, but still good style
    Thread.currentThread().interrupt(); 
}

If this last snippet is the whole run method of the thread being interrupted, you can get by without setting the interrupted status again, but if you have components being used by other parts you don't want one badly-behaved part to squelch the interrupted flag so that other code in the thread is not aware of the interruption.

Nathan Hughes
  • 94,330
  • 19
  • 181
  • 276
1

Thread.sleep() will clear the "interrupted status" before throwing InterruptedException. You need to call Thread.currentThread().interrupt() in the catch block, otherwise the while condition will most likely not succeed, because the thread will always be "not interrupted" when callMethod returns.

The exception is not caused by the interrupt() method, but by sleep() blocking on a thread that has been signaled as "interrupted". This is explained in more detail here. See also this answer.

Community
  • 1
  • 1
Javier
  • 12,100
  • 5
  • 46
  • 57