I was trying out the below code, I interrupted a user thread, when I print the value of isInterrupted it is returning false, I didn't got a single true value, over here the flag will get reset when the exception has been caught or on calling interrupted method.
Secondly, as per my understanding sleep method should throw and interruptedException in each iteration, the value in catch print, but it is throwing only once.
class ThreadInterruptt extends Thread
{
public void run()
{
for(int i = 0; i<100;i++)
{
try {
Thread.sleep(1000);
System.out.println(i);
System.out.println(isInterrupted());
} catch (InterruptedException e) {
System.out.println("Thread Interrupted");
}
}
}
}
public class ThreadInterrupt {
public static void main(String ag[]) throws InterruptedException
{
ThreadInterruptt t = new ThreadInterruptt();
t.start();
Thread.sleep(100);
t.interrupt();
}
}
You wouldn't ever get to the isInterrupted() check if you are interrupted: Thread.sleep() would have thrown an exception, and also it clears the interrupted status of the Thread, as described in the Javadoc.
And you're then discarding the fact the thread was interrupted (because you don't reset the interrupted flag on catching the exception), so it's not interrupted on the next iteration.
Related
if I override my run function as ,
Thread t = new Thread(){
public void run(){
try {
if(Thread.currentThread().isInterrupted()) {
doSomePrcocess() // is the isInerrupted() flag seeting to true?
return; //Terminates the current Thread
}
//otherwise
runScript();
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
and then If I call, Thread.currentThread().interrupt() from any point in the code, should the thread halt there and start running doSomeProcess() at that point? if yes, then how the interrupted flag gets to set true? If no, how to do this?
If thread is in sleeping or waiting state calling the interrupt() method on the thread, breaks out the sleeping or waiting state
throwing InterruptedException
If the thread is not in the sleeping or waiting state, calling the
interrupt() method performs normal behaviour and doesn't interrupt the thread but sets the interrupt flag to true.
Thread class has provision to deal with thread interruption as
public void interrupt()
public static boolean interrupted()
public boolean isInterrupted()
If you intend to go with the only once execution of doSomePrcocess then you have to go with which will check and clear the Thread interruption state for successive calls.
public static boolean interrupted()
Using below will only check the status and no modification.
public boolean isInterrupted()
I have got a running example with comments in your code below. Try running it a few times to see if it clarifies your concept.
Normally you would interrupt a thread from another thread and yes doSomeProcess will get invoked in the next cycle of the loop which could be 1 ms after the thread was interrupted or 1 hour after depending on the logic implemented in your methods.
public class InterruptTest {
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread() {
public void run() {
while (true) {
try {
if (Thread.currentThread().isInterrupted()) {
doSomePrcocess(); // is the isInerrupted() flag seeting to true? - Yes
return; // Terminates the current Thread - yes
}
// otherwise
runScript();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void runScript() {
System.out.println("runScript interrupted status:" + this.isInterrupted());
sleepy(100);
}
private void doSomePrcocess() {
System.out.println("doSomePrcocess interrupted status:" + this.isInterrupted());
sleepy(500);
}
private void sleepy(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Thread.currentThread().interrupt(); // try commenting this out to see what happens.
}
}
};
t.start();
Thread.sleep(1000);
t.interrupt(); // generally you would call interrupt on another thread.
}
}
No, it doesn't work like that. The isInterrupted method checks if the flag is set, it does not declare a handler. There is no way to define a central handler that will automatically be called when a thread is interrupted. What you can do is to catch InterruptedException and call the handler, plus check the interrupt flag regularly to see if it is time to stop.
I want to start a thread, interrupt it and start a new thread. The Problem is, that this doesn't really work. The first thread starts and gets interrupted, but the following thread gets interrupted before it even can start. So interrupt() interrupts the old and the new thread. The output looks like this:
run()-method starts
Thread Counter:0
Thread Counter:1
Thread Counter:2
Thread Counter:3
Thread Counter:4
Thread Counter:5
Thread Counter:6
8 seconds are over
Thread is not null
Thread will be interrupted now
catch
run()-method starts
catch
8 seconds are over
Thread is not null
Thread will be interrupted now
....
You can see that the thread starts the first time. Then the thread gets interrupted and 'catch' is called. So far, so good. After this, the next thread is going to start, but this time the thread gets interrupted immediately and 'catch' is called right after 'run()-method starts'.
So, I can't figure out why this is happening. I don't want two threads being interrupted in quick succession.
Here is my code:
public class MyRunnable {
static Thread myThread;
static boolean stop;
static Runnable myRunny = new Runnable() {
#Override
public void run() {
System.out.println("run()-method starts");
try {
int j = 0;
while (!stop) {
Thread.sleep(1000);
System.out.println("Thread Counter:"+j);
j++;
}
} catch (InterruptedException e) {
System.out.println("catch");
myThread.interrupt();
}
};
};
public static void main(String[] args){
myThread = null;
while(true) {
stop = false;
if(myThread != null) {
System.out.println("Thread is not null ");
System.out.println("Thread will be interrupted now");
myThread.interrupt();
}
myThread = new Thread(myRunny);
myThread.start();
try {
Thread.sleep(8000);
System.out.print("8 seconds are over "+ "\n");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
catch (InterruptedException e) {
System.out.println("catch");
myThread.interrupt();
}
myThread field is replaced with new reference before calling myThread.interrupt(), so you interrupt the new thread!
So interrupt() interrupts the old and the new thread.
Your diagnosis is incorrect. A call to Thread.interrupt will interrupt one thread once.
What your example is doing is interrupting one thread, and that thread is catching InterruptedException and interrupting a second thread in the exception handler. Two calls to interrupt are being made in quick succession on different threads.
I don't want two threads being interrupted in quick succession.
Well change
} catch (InterruptedException e) {
System.out.println("catch");
myThread.interrupt();
}
to
} catch (InterruptedException e) {
System.out.println("catch");
}
I have written the following code where the start method is supposed to wait until the stop method notifies it. But during the execution the log line below the start method gets printed though I have specified it to wait. Below shown is my start method implementation is as follows.
private static boolean stopThread = false;
public static void start(String[] args) {
startThread();
synchronized (serviceThread) {
try {
while(stopThread) {
serviceThread.wait();
}
LOGGER.log(Level.INFO, "Thread: Just after wait method");
} catch (InterruptedException e) {
LOGGER.log(Level.INFO, "'Wait' interrupted: " + e.getMessage());
}
}
}
Below shown is my stop method implementation.
public static void stop(String[] args) {
if (serviceThread != null) {
LOGGER.log(Level.INFO, "Stopping the thread");
serviceThread.interrupt();
LOGGER.log(Level.INFO, "Thread: Successfully interrupted");
synchronized (serviceThread) {
LOGGER.log(Level.INFO, "About to notify");
serviceThread.notify();
stopThread = true;
}
stopPlugins();
kubeLogManager.closeLogger();
messageBus.terminateMessageBus();
System.exit(0);
} else {
LOGGER.log(Level.INFO, "No thread to interrupt");
}
}
Why does that log line below the wait method get printed even before the stop method has been called? Please advice.
See the documentation for Object.wait:
https://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#wait()
interrupts and spurious wakeups are possible, and this method should always be used in a loop:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
You should use a variable to indicate when stop() has been called, and set it before you call notify(). Also, it's safer to use notifyAll(), since it still works if you somehow get another thread waiting on the object.
class Thread3_1 extends Thread {
public static int count = 0;
String tname1;
public Thread3_1(String threadname) {
tname1 = threadname;
}
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname1 + " : " + i);
count++;
if (count == 2) {
try {
sleep(1000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (isInterrupted()) {
System.out.println("Stop Thread");
return;
}
}
}
class Thread3_2 extends Thread {
String tname2;
public Thread3_2(String threadname) {
tname2 = threadname;
}
#Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname2 + " : " + i);
if (i == 5) {
Thread.currentThread().interrupt();
System.out.println("Going to interrupt Thread1");
}
}
}
}
Thread is executing after giving interrupt()
Interrupting a thread just sets an interrupt flag to true for this thread.
It's the responsibility of the thread itself to regurlarly check the value of this flag and stop executing ASAP (by returning from the run() method) as soon as it's true.
When the interrupt flag is set while the thread is sleeping (or when it's blocked inside a bocking call like wait(), await(), etc.), an InterruptedException is thrown by the blocking method. It's also the responsibility of the thread to cacth this exception and stop executing ASAP.
Your first thread regularly checks the flag and exits when it's true, but fails to do so when an InterruptedException is caught.
Your second thread interrupts itself, but doesn't return from its run() method when it does so.
You interrupt Thread3_2 and not Thread3_1.
In the run method of Thread3_2 you are calling
Thread.currentThread().interrupt();
This will send an interrupt to the current executing thread and this is an instance of Thread3_2. If you want to interrupt Thread3_1 you need a reference to that thread.
For example:
class Thread3_2 extends Thread{
Thread threadToInterrupt;
public Thread3_2(Thread threadToInterrupt) {
this.threadToInterrupt = threadToInterrupt;
}
#Override
public void run() {
for (int i = 1; i <= 10; i++) {
System.out.println(tname2+ " : " +i);
if(i == 5){
threadToInterrupt.interrupt();
System.out.println("Going to interrupt Thread1");
}
}
}
}
The thread you are interrupting must be designed to deal with the interruption request, by exiting gracefully from the run() method. That means making sure that InterruptedExceptions cause the code to break out of loops. It also means checking the interrupted flag periodically inside loops. There are other scenarios which are harder to deal with, such as non-interruptible IO operations.
It is also a good practice that the target thread re-marks itself as interrupted, so that the callers up in the call stack also get an indication of the interruption (Use Thread.currentThread().interrupt() in catch statements).
As noted above you need to interrupt Thread3_1 and not Thread3_2.
After applying this fix you will still have one issue left:
try {
sleep(1000);
count = 0;
} catch (InterruptedException e) {
e.printStackTrace();
}
So if at sleep interrupt happens, interrupt flag will be cleared and isInterrupted() method will return false, so below condition will not be met:
if (isInterrupted()) {
System.out.println("Stop Thread");
return;
}
So you need to handle this in catch block as well, i.e. return if in catch (got interrupted)
From the Java Tutorials:
Many methods that throw InterruptedException, such as sleep, are
designed to cancel their current operation and return immediately when
an interrupt is received.
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.*
*In other words: Other methods that do not throw InterruptedException must periodically invoke
Thread.interrupted, which returns true if an interrupt has been
received.
Explained here: http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
I just learned from sun's document that when i invoke thread.stop() method, the run() method will be terminated as the ThreadDeath error thrown out, and also release all the locks this thread holds, how to prove it?
I tried my test program, shown below:
public static void main(String[] args) {
final Object lock = new Object();
try {
Thread t = new Thread() {
public synchronized void run() {
try {
synchronized (lock) {
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++)
System.out.println("runing.." + i);
System.out
.println((System.currentTimeMillis() - start) / 1000);
}
} catch (Throwable ex) {
System.out.println("Caught in run: " + ex);
ex.printStackTrace();
}
}
};
t.start();
// Give t time to get going...
Thread.sleep(100);
t.stop(); // EXPECT COMPILER WARNING
} catch (Throwable t) {
System.out.println("Caught in main: " + t);
t.printStackTrace();
}
}
Only if i put an wait() in the run() method, then i can catch the ThreadDeath error, does anyone know the details of how jvm handle stop()?
public static void main(String[] args) {
final Object lock = new Object();
try {
Thread t = new Thread() {
public synchronized void run() {
try {
synchronized (lock) {
wait();
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++)
System.out.println("runing.." + i);
System.out
.println((System.currentTimeMillis() - start) / 1000);
}
} catch (Throwable ex) {
System.out.println("Caught in run: " + ex);
ex.printStackTrace();
}
}
};
t.start();
// Give t time to get going...
Thread.sleep(100);
t.stop(); // EXPECT COMPILER WARNING
} catch (Throwable t) {
System.out.println("Caught in main: " + t);
t.printStackTrace();
}
}
The simple answer is that the jvm has no reliable way to stop a thread. To stop or interrupt a thread, the target thread needs to cooperate by entering some interrupt-able state, such as sleep() or wait().
The Thread.stop() method has been deprecated for this reason (among others). See http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html for more details.
I do not think that I can explain better than Sun.
Here are the quotes from official Javadoc:
Deprecated. This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many 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. If the target threalink textd waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait. For more information, see Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?.
See here:
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html
that is because the thread executes before your current thread comes out of sleep and calls the t.stop.
The Thread.stop() doesn't stop a thread. Instead it call Thread.stop(new ThreadDeath()) which triggers the thread to throw this Error, which is silently ignored by default. i.e. if you throw any other Throwable the uncaughtException will print it to System.err. From ThreadGroup
public void uncaughtException(Thread t, Throwable e) {
if (parent != null) {
parent.uncaughtException(t, e);
} else {
Thread.UncaughtExceptionHandler ueh =
Thread.getDefaultUncaughtExceptionHandler();
if (ueh != null) {
ueh.uncaughtException(t, e);
} else if (!(e instanceof ThreadDeath)) {
System.err.print("Exception in thread \""
+ t.getName() + "\" ");
e.printStackTrace(System.err);
}
}
}
There is nothing else special/magical about this error. Your thread will unwind in the same manner at it would if you threw new ThreadDeath(). For comparison, try
thread.stop(new RuntimeException());
The explanations about Thread.stop are pretty much right on. The proper way to build a cooperative runnable is as follows:
public class MyRunnable implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
public void run() {
// do stuff
if (stopped) {
// cleanup and return;
}
// do more stuff
if (stopped) {
// cleanup and return;
}
}
}
Runnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
r.stop();
t.join(); // if you want to wait for it to die.
OR
public class MyRunnable implements Runnable {
public void run() {
// do stuff
if (Thread.currentThread().isInterrupted()) {
// cleanup and return;
}
// do more stuff
if (Thread.currentThread().isInterrupted()) {
// cleanup and return;
}
}
}
Runnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
t.interrupt();
t.join(); // if you want to wait for it to die.
Note that in either case, you have strategic stop points in your code where you're checking to see if you should continue processing. The second approach has the advantage that interrupt aware operations like Thread.sleep and java.nio based I/O operations can be immediately interrupted and don't have to wait for your stop point. Instead they would throw an InterruptedException immediately (or in the case of NIO a ClosedByInterruptException). Note that standard java.io based I/O is not interrupt aware, and you'll have to wait for one of your coded stop points.
The real answer is that the stop method of class Thread calls the private stop1 method which is synchronized. As your implementation of the thread's run method is also synchronized the stop1 method cannot be entered until the run method is exited.