Different behaviour when calling thread.isInterrupted and printing the result - java

I am bit confused with the behaviour of thread.isInterrupted in the program below.
public class ThreadPractice {
public static void main(String args[]) throws InterruptedException {
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println("Starting thread..." + Thread.currentThread().getName());
Thread.sleep(10000);
System.out.println("Waking up");
}catch(InterruptedException e){
System.out.println("Thread is interrupted!!!");
Thread.currentThread().interrupt();
}
}
});
t.start();
Thread.sleep(2000);
t.interrupt();
//System.out.println(!t.isInterrupted());
while(!t.isInterrupted()){
System.out.println("Current thread not interrupted!!!");
}
}
}
When executing the above program as such, it prints,
Starting thread...Thread-0
Thread is interrupted!!!
But when I uncomment the System.out statement to print the interrupt status, it runs into an infinite loop printing "Current thread not interrupted"
I am not able to figure out exactly what difference System.out statement makes.

Note that I don't always get an infinite loop.
I suspect it is due to the interleaving of operations. It helps to also check if the thread is alive:
System.out.println("Current thread not interrupted!!! Alive? " + t.isAlive());
If the thread is not alive, its interrupted status is false.
I get an output like:
Starting thread...Thread-0
Thread is interrupted!!!
Current thread not interrupted!!! Alive? true
Current thread not interrupted!!! Alive? false
[infinite loop]
I guess the first loop sees the thread not interrupted because the InterruptedException has removed the flag - then you reset the flag with interrupt() in the run() method and the thread can finish and is not alive any more.
The next loop check sees it not alive and you start an infinite loop.
An interesting variation can be obtained by adding:
System.out.println("Exiting Thread!!!");
At the end of the run() method - it provides a delay long enough for the loop condition to be checked between the time the interrupted flag is reset and the time the thread dies.

Related

What if I join the terminated(dead) thread

Over here I'm trying to join a thread after it has been terminated, the code is working fine, but my question doesn't it should throw some error messageor any info?
public class MultiThreadJoinTest implements Runnable {
public static void main(String[] args) throws InterruptedException {
Thread a = new Thread(new MultiThreadJoinTest());
a.start();
Thread.sleep(5000);
System.out.println("Begin");
System.out.println("End");
a.join();
}
public void run() {
System.out.println("Run");
}
}
If you look at the source code of Thread::join you will notice that it calls Thread::join(timeout) method. And looking at the source code of this method we can see that it checks status of the thread in a loop by calling Thread::isAlive :
...
if (millis == 0 L) {
while (this.isAlive()) {
this.wait(0 L);
}
} else {
while (this.isAlive()) {
long delay = millis - now;
if (delay <= 0 L) {
break;
}
this.wait(delay);
now = System.currentTimeMillis() - base;
}
}
...
so if a Thread, that you call join on, is terminated - join will just return and do nothing.
I'm repeating info that is already in other answers and comments, but let me try and summarize, while adding explanation.
The point of thread.join() is to wait for the thread to terminate. That's what it tells you in the documentation for join:
Waits for this thread to die.
Waiting for a terminated thread to terminate is pretty straightforward (!), and there seems to be no logical reason why waiting for a terminated thread to terminate should be considered an error. You want to know when the thread finishes. It has.
More significantly, if the caller had to ensure that a thread had not terminated before waiting for it to terminate, that would create a timing window that every caller would have to compensate for. The trivial sequence
Thread t = new Thread(…);
t.start();
t.join();
would be prone to failure due to its inherent race hazard. In other words, that would be a bad way to design join.
No, Thread.join() will return instantly if the thread is already dead
Thread will start the execution. will print Run then thread will sleep for 5 seconds and will print Begin following by End
Output on the console:
Run
---- 5 seconds sleep ------
Begin
End

How the execution order of interrupt is working in this program?

I was reading the implementation of interrupt in Java, but I could not figure out how the control is flowing?
The code snippet is:
public class Main implements Runnable
{
Thread t;
Main()
{
t = new Thread(this);
t.start();
t.interrupt();
if (!t.interrupted())
{
System.out.println("TRUE");
}
}
public void run()
{
try
{
System.out.println("Thread is in running state");
Thread.sleep(1000);
}
catch (InterruptedException e)
{
System.out.print(t.getName() + " interrupted");
}
}
public static void main(String args[])
{
new Main();
}
}
As per my understanding, by seeing the executing order in constructor it should be:
Thread is in running state
Thread-0 interrupted
TRUE
But this is WRONG.
The correct output is:
TRUE
Thread is in running state
Thread-0 interrupted
So please explain how this execution order work and why?
Edit 1:
As pointed out that calling t.interrrupted() is misleading so I changed the constructor to:
Main()
{
t = new Thread(this);
t.start();
t.interrupt();
if (!Thread.interrupted())
{
System.out.println("TRUE");
}
}
So now the output is:
TRUE
Thread is in running state
Thread-0 interrupted
Now the questions are,
Since the thread is in the non-runnable state when t.interrupt() was called, then what does t.interrupt() do in that case?
Why the last line of output is printed? From where does it get interrupt, because t.interrupt was executed when the thread was in the non-runnable state.
First, you are calling the wrong method.
As pointed out in another answer, interrupted() is a static method that always checks the current thread's interrupt status. If you want to check t's status, you should call t.isInterrupted().
Second, you have to remember that start() does not guarantee that the thread begins execution immediately. In fact, that will rarely happen. The new thread will only actually begin execution when the scheduler tells it to do so.
So, what is happening is:
you are calling start(), but the thread isn't actually starting yet
you are checking the wrong thread, since the current thread obviously isn't interrupted
the new thread starts running and is immediately interrupted due to the earlier interrupt() call
As for the answers to the EDIT:
you corrected the construct, but in the wrong way. It still checks the current thread, which is not getting interrupted
the last line is printed since the new thread does get interrupted, so when it starts it has its interrupted flag on - it immediately throws the exception
if (!t.interrupted())
This line is misleading. interrupted() is a static method that checks if the current thread has been interrupted, not the named thread. It would be a lot better if it were written:
if (!Thread.interrupted())

Thread creation by extending Thread class

This is a simple example about creating a thread by extending the Thread class.
class Count extends Thread {
Count() {
super("my extending thread");
System.out.println("my new thread is started " + this);
start();
}
#Override
public void run() {
try {
for (int i = 0; i < 10; i++) {
System.out.println("count " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("my thread run is over");
}
}
}
public class Multi2 {
public static void main(String[] args) {
Count c = new Count();
try {
while (c.isAlive()) {
System.out.println("main thread is alive untill child thread is alive");
Thread.sleep(1500);
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println("main thread is over");
}
}
}
And my output was this.
my new thread is started Thread[my extending thread,5,main]
main thread is alive untill child thread is alive
count 0
count 1
main thread is alive untill child thread is alive
count 2
main thread is alive untill child thread is alive
count 3
count 4
main thread is alive untill child thread is alive
count 5
main thread is alive untill child thread is alive
count 6
count 7
main thread is alive untill child thread is alive
count 8
main thread is alive untill child thread is alive
count 9
my thread run is over
main thread is over
My questions are,
01. How come main thread is alive untill child thread is aliveoutput printed before count 0
count 1
02.How come main thread is alive untill child thread is aliveoutput keep printing withing the output of run() method?
Please help me to figure this out.
Thank you.
Count has this line:
Thread.sleep(1000);
Your main program has this line:
Thread.sleep(1500);
Clearly, you're going to get 2 main prints for every 3 count prints. That's why 0 and 1 are next to each other.
As for why you see the main print before the count prints, you can see this:
Count c = new Count();
try {
while (c.isAlive()) {
System.out.println("main thread is alive untill child thread is alive");
Thread.sleep(1500);
You've fired off your c but until your JVM performs a context switch to actually run that thread, you might not see results. The truth is you may, on some systems, see your counter before that. Often, because it's so close to when it kicks off and hasn't yielded yet, you'll see the main print before the counter.
For your second part, your main thread is... keeps printing because it has a loop that tells it to print until your counter thread is no longer alive. They both use System.out so when you look at your console you see them both there.

How does interrupting a future work with single thread executors?

How does Executor.newSingleThreadExecutor() behave if I am frequently scheduling tasks to run that are being cancelled with future.cancel(true);?
Does the single thread spawned by the executor get interrupted (so the future code needs to clear the interrupt), or does the interrupt flag get automatically cleared when the next future starts up.
Does the Executor need to spawn an additional thread on every interrupt to be used by the remaining task queue?
Is there a better way?
Good question, I don't find this documented anywhere, so I would say it is implementation dependent.
For example OpenJDK does reset the interrupted flag before every executed task:
// If pool is stopping, ensure thread is interrupted;
// if not, ensure thread is not interrupted. This
// requires a recheck in second case to deal with
// shutdownNow race while clearing interrupt
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
Snippet from from OpenJDK jdk8u ThreadPoolExecutor#runWorker source.
The following sample program demonstrates that the interrupt is called on the thread if you call the cancel method with true. You can even see that it is reusing the same thread. The cancel returns a boolean which indicates if the cancellation was successful. The javadoc of this method is also clear enough.
class Task implements Callable<String> {
#Override
public String call() throws Exception {
try {
System.out.println("Thread name = " + Thread.currentThread().getName());
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
System.out.println("Interrupted");
return "Interruped";
}
return "X";
}
}
public class Testy {
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService =
Executors.newSingleThreadExecutor();
int count = 0;
while (true) {
System.out.println("Iteration " + count++);
Future<String> submit = executorService.submit(new Task());
Thread.sleep(500);
submit.cancel(true);
}
}
}
Output looks like below
Iteration 0
Thread name = pool-1-thread-1
Iteration 1
Interrupted
Thread name = pool-1-thread-1
Iteration 2
Interrupted

Stopping thread Immediately

I want to stop a running thread immediately. Here is my code:
Class A :
public class A() {
public void methodA() {
For (int n=0;n<100;n++) {
//Do something recursive
}
//Another for-loop here
//A resursive method here
//Another for-loop here
finishingMethod();
}
}
Class B:
public class B() {
public void runEverything() {
Runnable runnable = new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
A a = new A();
a.methodA();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
My problem is that i need to be able to stop the thread in Class B even before the thread is finished. I've tried interrupt() method, but that doesn't stop my thread. I've also heard about using shared variable as a signal to stop my thread, but I think with long recursive and for-loop in my process, shared-variable will not be effective.
Any idea ?
Thanks in advance.
Thread.interrupt will not stop your thread (unless it is in the sleep, in which case the InterruptedException will be thrown). Interrupting basically sends a message to the thread indicating it has been interrupted but it doesn't cause a thread to stop immediately.
When you have long looping operations, using a flag to check if the thread has been cancelled is a standard approach. Your methodA can be modified to add that flag, so something like:
// this is a new instance variable in `A`
private volatile boolean cancelled = false;
// this is part of your methodA
for (int n=0;n<100;n++) {
if ( cancelled ) {
return; // or handle this however you want
}
}
// each of your other loops should work the same way
Then a cancel method can be added to set that flag
public void cancel() {
cancelled = true;
}
Then if someone calls runEverything on B, B can then just call cancel on A (you will have to extract the A variable so B has a reference to it even after runEverything is called.
I think you should persevere with using Thread.interrupt(). But what you need to do to make it work is to change the methodA code to do something like this:
public void methodA() throws InterruptedException {
for (int n=0; n < 100; n++) {
if (Thread.interrupted) {
throw new InterruptedException();
}
//Do something recursive
}
// and so on.
}
This is equivalent declaring and using your own "kill switch" variable, except that:
many synchronization APIs, and some I/O APIs pay attention to the interrupted state, and
a well-behaved 3rd-party library will pay attention to the interrupted state.
Now it is true that a lot of code out there mishandles InterruptedException; e.g. by squashing it. (The correct way to deal with an InterruptedException is to either to allow it to propagate, or call Thread.interrupt() to set the flag again.) However, the flip side is that that same code would not be aware of your kill switch. So you've got a problem either way.
You can check the status of the run flag as part of the looping or recursion. If there's a kill signal (i.e. run flag is set false), just return (after whatever cleanup you need to do).
There are some other possible approaches:
1) Don't stop it - signal it to stop with the Interrupted flag, set its priority to lowest possible and 'orphan' the thread and any data objects it is working on. If you need the operation that is performed by this thread again, make another one.
2) Null out, corrupt, rename, close or otherwise destroy the data it is working on to force the thread to segfault/AV or except in some other way. The thread can catch the throw and check the Interrupted flag.
No guarantees, sold as seen...
From main thread letsvsay someTask() is called and t1.interrput is being called..
t1.interrupt();
}
private static Runnable someTask(){
return ()->{
while(running){
try {
if(Thread.interrupted()){
throw new InterruptedException( );
}
// System.out.println(i + " the current thread is "+Thread.currentThread().getName());
// Thread.sleep( 2000 );
} catch (Exception e) {
System.out.println(" the thread is interrputed "+Thread.currentThread().getName());
e.printStackTrace();
break;
}
}
o/P:
java.lang.InterruptedException
at com.barcap.test.Threading.interrupt.ThreadT2Interrupt.lambda$someTask$0(ThreadT2Interrupt.java:32)
at java.lang.Thread.run(Thread.java:748)
the thread is interrputed Thread-0
Only t1.interuuption will not be enough .this need check the status of Thread.interrupted() in child thread.

Categories