Thread can't catch InterruptionException - java

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.

Related

how to stop a thread with thread interrupt method

I am trying to learn thread interrupt and how to make a thread terminate without calling stop.
public class Test implements Runnable{
static Thread threadTest=null;
public static void main(String args[]){
System.out.println("Hello i am main thread");
Test thread= new Test();
threadTest= new Thread(thread);
threadTest.start();
}
private static void exitThread() {
threadTest.interrupt();
}
#Override
public void run() {
boolean run = true;
while (run) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
run = false;
}
}
}
}
Output
Hello i am main thread
Sleeping
Processing
Sleeping
I am unable to understand why Sleeping is printed second time and interrupted exception is thrown second time rather than first time.I have checked posts where volatile keyword is used to stop a thread in java.but i am unable to understand how that will be used in this scenario as thread gets stopped with interrupt.
In order to see the thread being interrupted instead of entering the sleep method a second time, change the while loop test in the run method to check the interrupt flag:
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
try {
System.out.println("Sleeping");
Thread.sleep((long) 10000);
exitThread();
System.out.println("Processing");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
The thread will sleep, then set its own interrupt flag, then check the flag and terminate. InterruptedException would be thrown by the Thread#sleep method only if the thread was sleeping while the interrupt flag was set.
Your local boolean variable is not needed. If Thread#sleep throws an InterruptedException (which it won't in this example because the thread checks the interrupted flag and leaves the while loop) then the interrupt flag is cleared, restoring it in the catch block allows the while test to see that the thread was interrupted.
In real programs the thread would be interrupted from another thread, there's no reason for a thread to interrupt itself (it can just return instead).
Calling Thread.interrupt() just sets a flag for the thread. It doesn't do anything else. Only blocking methods (those usually declare throws InterruptedException) respond to that flag being set (by throwing). The flag is sticky in that it remains set until its cleared.
So the first call to the sleep method just runs normally (the interrupted flag isn't set yet). After that your code does nothing that acts on the interrupted status, until the second loop iteration where the sleep call detects the interrupted status and throws the exception.
You can use Thread.interrupted() or Thread.isInterrupted() to check the interrupted status at any time (beware that interrupted() also clears the interrupted status if it was set).
here you creating another thread Test class but "main" has its own thread , so the new thread you created is interpreted .
Here in this code you are interrupting the new created thread Thread-0 not main thread,when you execute this code you are making thread to sleep before it enters the method exitThread() ,so it is displaying the processing, but if you try to put thread sleep after you enter exitthread() you will have your answer
Like in this code:
public class Test implements Runnable {
public boolean run = true;
#Override
public void run() {
while (run) {
try {
System.out.println("Sleeping...");
exitThread();
Thread.sleep(10000);
System.out.println("Processing...");
} catch (InterruptedException e) {
System.out.println("Thread intreputted " + e);
run = false;
}
}
}
private void exitThread() {
Thread.currentThread().interrupt();
if (Thread.currentThread().isInterrupted())
System.out.println(Thread.currentThread().getName()
+ " is intreputted");
else
System.out.println("alive");
}
public static void main(String[] args) {
System.out.println("hi I am current thread------>"
+ Thread.currentThread().getName());
Test test = new Test();
Thread thread = new Thread(test);
thread.start();
}
}
Hope it will be helpfull

Java MultiThreading Stop Method

What will happen if we access a thread which was stopped using stop() method.
UserThread t = new UserThread();
t.start();
System.out.println(t.getName());
System.out.println(t.getState());
t.stop();
System.out.println(t.getState());
Anyhow stop() method is deprecated in java8, but need the output for above. Is it possible to access the thread which was stopped means in terminated state?
Thanks in advance.
Why is Thread.stop deprecated?
Because it is inherently unsafe. Stopping a thread causes it to unlock
all the monitors that it has locked. (The monitors are unlocked as the
ThreadDeath exception propagates up the stack.) If any of the objects
previously protected by these monitors were in an inconsistent state,
other threads may now view these objects in an inconsistent state.
Such objects are said to be damaged. When threads operate on damaged
objects, arbitrary behavior can result. This behavior may be subtle
and difficult to detect, or it may be pronounced. Unlike other
unchecked exceptions, ThreadDeath kills threads silently; thus, the
user has no warning that his program may be corrupted. The corruption
can manifest itself at any time after the actual damage occurs, even
hours or days in the future.
What should I use instead of Thread.stop?
Most uses of stop should be replaced by code that simply modifies some
variable to indicate that the target thread should stop running. The
target thread should check this variable regularly, and return from
its run method in an orderly fashion if the variable indicates that it
is to stop running. To ensure prompt communication of the
stop-request, the variable must be volatile (or access to the variable
must be synchronized).
For example, suppose your applet contains the following start, stop and run methods:
private Thread blinker;
public void start() {
blinker = new Thread(this);
blinker.start();
}
public void stop() {
blinker.stop(); // UNSAFE!
}
public void run() {
while (true) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
You can avoid the use of Thread.stop by replacing the applet's stop and run methods with:
private volatile Thread blinker;
public void stop() {
blinker = null;
}
public void run() {
Thread thisThread = Thread.currentThread();
while (blinker == thisThread) {
try {
Thread.sleep(interval);
} catch (InterruptedException e){
}
repaint();
}
}
If you are interested in seeing what is the state of a thread after you call stop you can suppress the deprecation warning by adding #SuppressWarnings("deprecation") before your test class definition.
For instance try the following code:
#SuppressWarnings("deprecation")
class test {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
while(true) {
try {
Thread.sleep(1000);
}catch(Exception e) {}
}
}
};
t.start();
System.out.println(t.getName());
System.out.println(t.getState());
t.stop();
try {
Thread.sleep(1000); // wait for stop to take effect
}catch(Exception e) {}
System.out.println(t.getState());
}
}
Spoiler alert: the status is TERMINATED
Its advised not use stop() method in Thread class since this is deprecated.
If you want to abort the thread execution use interrupt()
class IntThread extends Thread{
public void run(){
try{
Thread.sleep(1000);
System.out.println("Didn't Interrupt me !!!");
}catch(InterruptedException e){
throw new RuntimeException("Thread interrupted..."+e);
}
}
public static void main(String args[]){
IntThread t1=new IntThread();
t1.start();
try{
t1.interrupt();
}catch(Exception e){System.out.println("Exception handled "+e);}
}
}
You can refer link for more details about interrupt.

Why do I need to handle an exception for Thread.sleep()?

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

Destroying a thread, having a never ending function int its run() method?

In my run() method of my Thread class, I am calling a never ending function.
I need the thread to run only for a specific duration.
Am not able to control the thread once its started, Is their any way to destroy it?
I have tried yield(), sleep(), etc...
PS - I cannot change the never ending function
From oracle Java Docs:
public void run(){
for (int i = 0; i < inputs.length; i++) {
heavyCrunch(inputs[i]);
if (Thread.interrupted()) {
// We've been interrupted: no more crunching.
return;
}
}
}
Your thread should check interrupted condition after each loop to see if it was interrupted. If you are calling a method that just does while(true){} then I am afraid there is no way interrupting it and stop() MUST never be called on a thread.
It is the programmers responsibility to make a long running method responsive to interrupts.
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html answers all your questions.. particularly section What should I use instead of Thread.stop?
Hope it helps
This could be too much, but this is how I would solve it, if you do not want to mess with Interrupt.
public class ThreadTest {
public static void main(String[] args) throws InterruptedException {
ThreadTest test = new ThreadTest();
test.go();
}
void go() throws InterruptedException{
ExecutorService service = Executors.newSingleThreadExecutor();
service.execute(new LongRunnable());
if(!service.awaitTermination(1000, TimeUnit.MILLISECONDS)){
System.out.println("Not finished within interval");
service.shutdownNow();
}
}
}
class LongRunnable implements Runnable {
public void run(){
try{
//Simultate some work
Thread.sleep(2000);
} catch(Exception e){
e.printStackTrace();
}
}
}
Basically you are wrapping your runnable in a ExecutorServie and if it's not finished within the interval, you basically kill it - send the interruption to it.

Interrupting looped threads in Java

I'm trying to understand how threads work in Java and currently investigating how to implement looped threads that can be cancelled. Here's the code:
public static void main(String[] args) throws Exception {
Thread t = new Thread() {
#Override
public void run() {
System.out.println("THREAD: started");
try {
while(!isInterrupted()) {
System.out.printf("THREAD: working...\n");
Thread.sleep(100);
}
} catch(InterruptedException e) {
// we're interrupted on Thread.sleep(), ok
// EDIT
interrupt();
} finally {
// we've either finished normally
// or got an InterruptedException on call to Thread.sleep()
// or finished because of isInterrupted() flag
// clean-up and we're done
System.out.println("THREAD: done");
}
}
};
t.start();
Thread.sleep(500);
System.out.println("CALLER: asking to stop");
t.interrupt();
t.join();
System.out.println("CALLER: thread finished");
}
The thread I create is indended to be interrupted sooner or later. So, I check isInterrupted() flag to decide whether I need to go on and also catch InterruptedException to handle cases when I'm in a kind of waiting operation (sleep, join, wait).
Things I'd like to clarify are:
Is it fine to use interruption mechanism for this kind of task? (comparing to having volatile boolean shouldStop)
Is this solution correct?
Is it normal that I swallow InterruptedException? I'm not really interested what was the piece of code where someone asked my thread to interrupt.
Are there any shorter ways to solve this problem? (the main point is having 'infinite' loop)
EDIT
Added call to interrupt() in catch for InterruptedException.
I am answering no. 3:
Basically the question is: What purpose does an Interrupted exception have? It tells you to stop blocking (e.g. sleeping) and return early.
There are two ways dealing with an InterruptedException:
Rethrow it, so the thread remains interrupted
set Thread.currentThread.interrupt() again and do your cleanup work. This way you can be sure that another method in your thread starting to sleep will throw again
Simply swallowing an InterruptedException is not a good idea regarding the purpose of such an interrupt which is to finally terminate. But you are only asked to interrupt so you still have time to clean up.
In this case this might be an 'overreaction' of myself, but typically such code is much more complicated and how do you know, that some follow-up-code in this Thread would not call a blocking method again?
EDIT
Otherwise I think what you're doing is fine. For me a bit surprising, though, because I never saw anyone in his own code actually doing it.
And interesting article explaining why can be found here: http://www.ibm.com/developerworks/java/library/j-jtp05236/index.html
Yes, it's fine. You should document how a Thread/Runnable must be stopped. You could add a dedicated stop method on your Runnable implementation that encapsulates the stopping mechanism. Either use interrupt, or use a dedicated boolean value, or both.
Yes, except the good practice is to restore the interrupt status when catching InterruptedException: Thread.currentThread().interrupt();
No, you should restore the interrupt status
None that I'm aware of
1) The way in your example is preferable to using a volatile flag (which is redundant since you already have the interrupted flag), according to the Java Concurrency in Practice book. It is how InterruptedExceptions were intended to be used.
2) Yes
3) you can eat the exception as long as you restore the interrupt flag status. The exception doesn't represent an error so eating it doesn't lose any information, it is purely a means of transferring control. (Restoring the interrupt flag status is important for cases where you have nested control structures that each need to be informed that the thread is cancelling, for a simple example like yours it's good form but if it's missing it won't hurt anything.)
4) no
It's fine to use Interruption, but use them well. You have to re-throw Thread.currentThread().interrupt() in your catch. Here is a piece of code showing why :
public class MyThread extends Thread {
private static boolean correct = true;
#Override
public void run() {
while (true) {
// Do Something 1
for (int i = 0; i < 10; i++) { // combined loop
// Do Something 2
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
if (correct)
Thread.currentThread().interrupt(); // reinterrupting
System.out.println("First Catch");
break; // for
}
}
try {
// Do Something 3
System.out.print("before sleep, ");
Thread.sleep(1000);
System.out.print("After sleep, ");
} catch (InterruptedException ex) {
if (correct)
Thread.currentThread().interrupt();
System.out.println("Second catch");
break; // while
}
}
System.out.println("Thread closing");
}
private static void test() throws InterruptedException {
Thread t = new MyThread();
t.start();
Thread.sleep(2500);
t.interrupt();
t.join();
System.out.println("End of Thread");
}
public static void main(String[] args)
throws InterruptedException {
test();
correct = false; // test "bad" way
test();
}
}
Another thing is, Interruptions don't always work when waiting on InputStreams. You then can use (for some) InterruptedIOException, but it won't always work. To understand these cases, you might want to try this piece of code :
public class Mythread extends Thread {
private InputStream in;
public Mythread(InputStream in) {
this.in = in;
}
#Override
public void interrupt() {
super.interrupt();
try {
in.close(); // Close stream if case interruption didn't work
} catch (IOException e) {}
}
#Override
public void run() {
try {
System.out.println("Before read");
in.read();
System.out.println("After read");
} catch (InterruptedIOException e) { // Interruption correctly handled
Thread.currentThread().interrupt();
System.out.println("Interrupted with InterruptedIOException");
} catch (IOException e) {
if (!isInterrupted()) { // Exception not coming from Interruption
e.printStackTrace();
} else { // Thread interrupted but InterruptedIOException wasn't handled for this stream
System.out.println("Interrupted");
}
}
}
public static void test1() // Test with socket
throws IOException, InterruptedException {
ServerSocket ss = new ServerSocket(4444);
Socket socket = new Socket("localhost", 4444);
Thread t = new Mythread(socket.getInputStream());
t.start();
Thread.sleep(1000);
t.interrupt();
t.join();
}
public static void test2() // Test with PipedOutputStream
throws IOException, InterruptedException {
PipedInputStream in = new PipedInputStream(new PipedOutputStream());
Thread t = new Mythread(in);
t.start();
Thread.sleep(1000);
t.interrupt();
t.join();
}
public static void main(String[] args) throws IOException, InterruptedException {
test1();
test2();
}
}

Categories

Resources