What if I join the terminated(dead) thread - java

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

Related

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())

Avoid waiting for a terminated thread

I'm having the problem that sometimes a thread that I've started finishes before I call wait() on it. It seems that this causes my program to wait for something that is not going to happen again (notify()). How can I make sure not to wait for a finished thread?
void someFunction() {
MyThread thread = new MyThread();
thread.start();
// .. some stuff that takes sometimes quite long
synchronized(thread) {
try {
thread.wait();
} catch(InterruptedException e) {
// ..
}
}
}
If you read the JavaDocs for Thread, it tells you NEVER EVER use wait, notify, or notifyAll on Thread objects. You should use join()
You are looking at the "lost notification" problem. (I.e., you are not using wait() in the proper way.)
When you call foo.wait(), you should always be waiting for some condition that you can explicitly test. E.g., like this:
boolean condition;
synchronized(foo) {
while (! condition) {
foo.wait();
}
doSomethingThatRequiresConditionToBeTrue();
}
When you do anything that makes the condition true, it should look like this:
synchronized(foo) {
doSomethingThatMakesConditionTrue();
foo.notify();
}
When you do anything that makes the condition false, it should look like this:
synchronized(foo) {
doSomethingThatMakesConditionFalse();
}
Notice that:
Any code that touches the condition is synchronized, and always synchronized on the same object.
It is impossible for foo.wait() to be called when the condition is true.
The wait() is called in a loop.
Point (2) is crucial, because foo.notify() does not do anything at all if there is no other thread waiting to be notified. A notification that nobody's waiting for is "lost". The foo object does not remember that it was notified.
Point (3) is important for two reasons. The main one is, if thread A calls foo.wait(), and then thread B makes the condition true and calls foo.notify(); There's no guarantee that the condition will still be true when the wait() call eventually returns in thread A. Some other thread could have made the condition false again. This is a very real scenario in many applications.
The other reason why point (3) is important is that the Java Language Specification permits foo.wait() to return even when foo.notify() has not been called. That's called a "spurious wakeup", and allowing it to happen makes it easier to implement a JVM on certain operating systems.
Instead of wait(), you can use :
thread.join()
But i dont know the context of your situation.
Calling wait on the Thread works some of the time because when a thread terminates it sends a notification to every thread waiting for it. But if the thread has already terminated before your current thread calls wait, then no notification will ever occur.
The advice to use join is correct, and James Large’s answer is correct that your code should wait in a loop with a condition variable. That is exactly what join is doing, if you look in the code for java.lang.Thread.join (where join without an argument defaults to 0, wait(0) means wait without a timeout):
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
It has a loop where it tests the Thread’s alive flag, and if it is true then it proceeds to wait. If the thread is already terminated then the thread won’t wait, so the case where the current thread waits after the joined thread is finished cannot occur.

Java: Thread doesn't work

I'm trying to start a thread in a for-loop. This task should only wait for a second (Thread.sleep()), so every time the loop starts over again, a new thread is started and it should cause the code after the thread to wait until it is executed.
public void count()
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new TimerClass());
t1.start();
String s = String.valueOf(i);
jLabel6.setText(s);
System.out.println(s);
}
}
public class TimerClass implements Runnable{
#Override
public void run()
{
try{
Thread.sleep(1000);
System.out.println("Timer");
} catch(InterruptedException e)
{
}
}
}
As you can see, I implemented in both methods System.out.println() to check if they are actually executed. I get this:
29
28
27
26
...//25 - 3
2
1
0
Timer
Timer
Timer
//in all 29 times Timer
So it should be 29, Timer, 28, Timer and so on, but it isn't.
Does anyone know what's wrong with the code?
Thanks a lot.
Your main loop that is starting the thread is likely dominating the CPU, so it finishes doing its entire loop and only then do the threads get a chance to go.
In fact, given that all of your threads sleep for an entire second and you're only looping 29 times, you're guaranteed that your loop will finish (and print all of the numbers) before your threads do. Add a sleep to your main loop if you want the threads to print - remember, the main loop doesn't stop when you start a thread.
You can join a thread to the main thread so first your thread will finished then main thread
public void count()
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new TimerClass());
t1.start();
t1.join();
String s = String.valueOf(i);
jLabel6.setText(s);
System.out.println(s);
}
}
Here is my code for spawning 2 threads or one thread depends on arrayList size but in my case this threads are doing much more complex tasks then just waiting 1 sec
for (int i = 0; i < array.size(); i += 2) {
Thread t1 = null;
Thread t2 = null;
if (i < array.size() - 1 && array.size() > 1) {
t1 = new Thread(array.get(i));
t2 = new Thread(array.get(i + 1));
t1.start();
t2.start();
}
else {
t2 = new Thread(array.get(i));
t2.start();
}
if (t1 != null)
t1.join();
if (t2 != null)
t2.join();
}
In my code I populate arrayList with Objects that Implements Runnable interface.
Even if you sleep the thread for 1ms, your results would be the same. If you can manage the thread to sleep for the time less than it takes to print the results, your result could be as expected. Here is my code where I have put the time of 1 ms but yet the results are the same.
public class MultiThreading implements Runnable
{
public void run()
{
try
{
Thread.sleep(1);
System.out.println("Timer");
}
catch(Exception e)
{
}
}
public static void main(String [] args)
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new MultiThreading());
t1.start();
String s = String.valueOf(i);
System.out.println(s);
}
}
}
If you comment out the Thread.sleep(1) method, then your results are as you expected.
Delay is much enough to let the for loop in count() to finish before is can print 'timer' from thread.
What is happening is that the thread you started starts executing and immediately goes to sleep. In the meantime, your loop just keeps running. As the whole point of threads is that they run asynchronously, I don't really understand why you think your main loop should be waiting for it to finish sleeping. The thread has started running and is now running independently of the main loop.
If you want to wait for the thread you just started to finish (in which case, you might as well use a method), then use one of the synchronisation primitives, i.e. Thread.wait().
What you actually want to do is block your main thread while another thread is running. Please don't use Thread#sleep statements, as these are unreliable in order to "make your application work". What you want to use instead is Thread#join. See dharr his code for an example.
Also, it's better to use Executors and ExecutorServices when creating threads or running async tasks.
Threads are interesting. Think of a virtual thread as a physical thread. There are many threads on the clothes you're wearing, all working at the same time to hold your shirt together. In virtual terms what Thread.start() does is start a thread on a different strand WHILE the following code continues to execute, (i.e. Two Threads work simultaneously like 2 runners run next to each other). Consider putting a break point right after Thread.start(). You'll understand.
For your desired effect, just put a Thread.sleep() in the main loop. This will cause an output of
29
Timer
28
Timer
// etc.
Hope this helped.
Jarod.
Another analogy to the threads in a shirt:
Think of threads as coworkers to your main programm (which is a thread itself). If you start a thread, you hand some work to this coworker. This coworker goes back to his office to work on this task. You also continue to do your task.
This is why the numbers will appear before the first thread/coworker will output anythig. You finished your task (handing out work to other coworkers) before he finished his.
If you want to give out some work and then wait for it to be finished, use t1.join() as suggested by others. But if you do this, it is senseless to create new Threads, because you don't (seem) to want to process something in parallel (with many coworkers) but in a specific order - you can just du it yourself.

infinite loop in a function called within a thread causes the thread to stay alive

public class Ex4 extends Thread {
boolean ans;
boolean change=false;
public boolean isPrime(long n, double maxTime) throws RuntimeException {
final Thread a;
Thread b;
final RuntimeException e;
final long num = n ;
final double mtime = maxTime;
a = new Thread(){
public void run(){
try{
ans = Ex4_tester.isPrime(num);
change=true;
}
catch ( RuntimeException exp){
throw exp;
};
}
};
a.start();
try {
sleep((long)mtime);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
if(a.isAlive()){
a.interrupt();
}
if(a.isInterrupted()){
throw new RuntimeException("time for check exceeded");
}
return ans;
}
}
all works fine, except sometimes Ex4_tester.isPrime goes into infinite loop (its ok, it should do that).
the problem that even though the thread gets interrupted the process keeps running and the thread doesnt actually stop
A thread getting interrupted doesn't stop it. It just causes the thread to get out of certain wait and sleep states. To have the thread exit an infinite loop based on input from another thread, put an explicit check against an Atomic<> in the loop and have the control thread modify the state of the atomic variable to where thread 'a' will exit the loop.
Only certain methods like Object.wait() will throw InterruptedException. If your thread doesn't call any of those methods, it won't get interrupted.
In other words, you can't asynchronously interrupt a Java thread. Very few threading systems support asynchronous interruption.
The most easy way is to set your thread to be daemon, that is call a.setDaemon(true) before start. That will make your process will be ended if this is only thread that stayed started.
If you want to interrupt your thread read this documentation for interrupt method
interrupt method causes InterruptedException only when the thread is in certain points of execution (such as sleep). Your code has invalid cancellation policy. You should consider another way of stopping your thread.
An interrupt requires an explicit check at a point where it is safe by design to interrupt a thread. If you don't perform this check (or call a method which does) the thread will keep running.

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