Waiting for a thread to finish with .join incosistent - java

Consider this code:
public class print extends Thread {
public void run() {
Out.print("Hello");
Out.println("World");
}
}
public class test {
public static void main (String[] args) {
Thread t1 = new print();
Thread t2 = new print();
Thread t3 = new print();
Thread t4 = new print();
Thread t5 = new print();
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
try {
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
}catch(InterruptedException e) {
}
}
}
The goal is to print out hello, than world in the next line.The output isn't right,and it is very inconsistent, meaning every few test it changes.I've never worked with threads,but I did some reaserch and it says that using this .join should wait for one thread to finish so that the next one starts. What am I doing wrong?
Thank you!

and it says that using this .join should wait for one thread to finish so that the next one starts
That is not what join does.
join blocks the current thread until the target thread is finished. It does not do anything about any other threads.
In your case, the main thread will wait for t1 to finish, then for t2 and so on. But it does nothing to schedule how t1 runs in relation to t2. In particular, it also does not delay starting t2. t2 starts when you said t2.start().
Okay,so how do I tell the others to wait as well?
Ideally you use higher level constructs like work queues and executor services instead of messing with low-level threading primitives.
If you do want to continue doing that, look at ReentrantLock or CountDownLatch. Or have t1 call t2.join().
I would probably use a CountDownLatch. Set up the latch to require five tickets, then each of your threads can print the first line, then block at the latch, and only when the latch releases (which happens when all five have arrived), they will continue to print the second line.
Also note that if you want to run these tasks in a sequence one after the other, you do not need multiple threads at all. Just do t1.run(); t2.run(); t3.run(); on the same thread.

Related

Why threads are not working?

Here is my following code:
private int counter = 0;
public void incC() {
counter++;
System.out.println("Counter is: "+counter + " "+Thread.currentThread().getName());
}
public void printC() {
System.out.println("Counter is: "+counter + " "+Thread.currentThread().getName());
}
public static void main(String args[]) throws Exception {
Stuff stuff = new Stuff();
Thread t1 = new Thread(() -> {
stuff.incC();
});
Thread t2 = new Thread(() -> {
stuff.printC();
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
Here's my output:
Counter is: 1 Thread-1
Counter is: 1 Thread-0
Here t1.join() is called first. So shouldn't thread t2 should wait for thread t1 to die?
How's it possible for thread t2 to output first before t1?
t1.join() makes the current thread wait for thread t1 to die. It has no effects on the timing of any other thread but the current one. You have started two threads and they will run concurrently with no ordering constraints.
I should also note that starting two threads only to have one wait for the other's death defeats the purpose of multithreading.
join() forces to wait current (in your case the main) thread to death of t1, so t2 continues to work
Order for thread execution is not fixed because they work in parallel
Both threads works in parallel and therefore no guarantee on which thread will finish first in your case.
If you want a specific thread to finish first you have to start it and join it with your main thread then start and join the second thread like follows.
t1.start();
t1.join();
t2.start();
t2.join();
Set names for the threads for better understanding.
Also change your question because your threads are working fine.

What is the difference between setting the priority for the main thread or not?

I have this Question :
Create and run a thread that writes "Hello friends" on screen. The main Thread waits for it only 500 milliseconds. Then run the program again after you give the created Thread lower priority than the main Thread. This time, the main Thread should wait for it 10 milliseconds. Do you notice anything? Why?
I want to know the difference that made by Thread.setPriority(n)
first code and second get the same output
first code
public class Q2 {
public static void main(String[] args) {
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
}
}
class Thread2 extends Thread{
#Override
public void run(){
try {
join(500);
System.out.println("Hello Friends from thread2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
seconde code
public class Q2 {
public static void main(String[] args) {
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
}
}
class Thread2 extends Thread{
#Override
public void run(){
try {
setPriority(MIN_PRIORITY);
join(500);
System.out.println("Hello Friends from thread2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
the main Thread should wait for it 10 milliseconds
That's not what your code does. The join should be in the main thread, not in the newly created thread:
Thread2 myThread = new Thread2();
myThread.start();
myThread.join(10);
I assume the whole idea of this exercise is to see the difference between two threads with different priorities. Giving a thread a lower priority may delay its scheduled execution. When the main thread waits for a smaller duration for the new thread to finish, the outputs of the two threads may interleave since the main thread may continue to reach the System.out before the second thread does.
The documentation of the Thread class explains what a thread priority is:
Every thread has a priority. Threads with higher priority are executed in preference to threads with lower priority.
In general, don't extend Thread, you should wrap a Runnable instead.
The Thread priority is
just a hint, the OS can and does ignore it if you don't have the right permissions.
It will only matter if you don't have free CPU. If you have free CPU every thread which wants to run can run.
it really won't matter if you are putting your thread to sleep. e.g. a join.
The only difference it could make is when your machine is very busy, it would take a little longer to wake up from the sleep. e.g. instead of taking say 500 to 501 ms to do the join, it might take 510 ms sometimes.
how can I use join method ?
The purpose of join is to wait for another thread to finish up to some time limit. If you join on yourself, this is effectively the same as Thread.sleep I suggest using Thread.sleep instead as this is less confusing.
First, from the documentation for Thread:
Waits at most millis milliseconds for this thread to die. A timeout of 0 means to wait forever.
So when you have two Thread instances, lets say the current one and a new one, you can cause the current thread to wait for the new one to die:
final Thread t = new Thread(() -> System.out.println("Test"));
t.start();
t.join();
So now our current thread (the one creating t) will wait for t to die, then continue. This method makes an asynchronous task synchronous.
Now, what does calling join in a Thread do? Well, it means that the thread will wait for itself to die. This is the same as TimeUnit.MILLISECONDS.sleep().
So what does your code actually do?
Well, main calls the following code:
Thread2 myThread = new Thread2();
myThread.start();
System.out.println("main thread");
There is nothing here that makes main wait for anything, main dies.
Now your Thread2 (terrible name for a class) does the following:
setPriority(MIN_PRIORITY);
join(500);
System.out.println("Hello Friends from thread2");
So it sets its own priority, it then waits for 500 milliseconds for itself to die. Obviously it doesn't die in that time. It then prints.
TL;DR: setPriority does next to nothing in this code
One further note, do not extends Thread, use a Runnable.

if daemon threads have low priority how it runs before all user threads completes?

I have read daemon threads are low priority threads and it runs only when no other user threads are alive. But the below code does not have any difference.
public class DaemonThreadTest {
public static void main(String[] args) {
DaemonThread d = new DaemonThread();
Thread t1 = new Thread(d,"daemon");
t1.setDaemon(true);
Thread t2 = new Thread(d,"Non-Daemon");
t1.start();
t2.start();
System.out.println("Main finished");
}}
class DaemonThread implements Runnable{
public void run(){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i=0;i<10;i++){
System.out.println(Thread.currentThread().getName()+ i);
}
}}
And the output is,
Main finished
Non-Daemon0
Non-Daemon1
Non-Daemon2
Non-Daemon3
Non-Daemon4
Non-Daemon5
Non-Daemon6
Non-Daemon7
daemon0
daemon1
daemon2
daemon3
daemon4
daemon5
daemon6
daemon7
daemon8
daemon9
Non-Daemon8
Non-Daemon9
Threading priorities are largely handled by the operating system and so it plays a big part in deciding when to allow Threads to run. For example I ran your code a couple of times and on one run I got this output:
Main finished
daemon0
daemon1
daemon2
daemon3
daemon4
daemon5
daemon6
daemon7
daemon8
daemon9
Non-Daemon0
Non-Daemon1
Non-Daemon2
Non-Daemon3
Non-Daemon4
Non-Daemon5
Non-Daemon6
Non-Daemon7
Non-Daemon8
Non-Daemon9
Which is almost a complete reverse to your results. Whilst you can try setting priorities manually it will still ultimately come down to how the operating system runs your threads.
Regarding Daemon threads, a daemon is like a 'sub-thread' (or child thread as I like to think :) ) of a user thread. This means it is linked/connected to a user Thread. In your case it is linked to the main thread, when the main thread ends the daemon will die with it. HOWEVER because you have another user Thread running (t2) the main method waits until that is finished. If you were to comment out t2 like so:
// Thread t2 = new Thread(d,"Non-Daemon");
t1.start();
// t2.start();
and then run your program you would likely find the daemon thread never runs because main ends too soon and when it exits takes the daemon thread with it.
Priority Check
Change your loop code statement to this:
System.out.println(Thread.currentThread().getName()+ i
+ " [Proirity] " + Thread.currentThread().getPriority());
And you can see the priority for yourself. Priority is scaled from 1 -10, when I ran it both t1 and t2 had priority 5 so netiher was lower than the other.

Is it possible to call Thread start() and join() in a single call?

I'm playing with threads in Java and i have a question about the join() method.
Let's say i have a SampleClass that extends Thread. I instantiate some new threads in the main but i want the thread's job to be completed sequentially using join().
public static void main(String[] args) {
for(int i=0; i<5; i++){
new SampleClass().start();
}
}
Is it possible to call immediately join()? ...something like this:
new SampleClass().start().join();
Or is there another approach to use? ...like this maybe:
new SampleClass().start();
try{Thread.currentThread().join();}catch(InterruptedException e){...}
Thank you very much
new SampleClass().start().join(); This is wrong.
You can achieve similar thing by
SampleClass samClass = new SampleClass();
samClass.start();
samClass.join()
The above code will have same effect as you wanted.
Now your problem is to run the Threads Sequentially. In most of these
cases you don't need threads to execute sequentially (But yes there are some scenarios).
Well If you do have to.
Then you can Do Like this
Thread t1 = ..
Thread t2 = ..
t1.start();
t1.join();
t2.start(); // t2 will start only when t1 dies
t2.join(); //
t3.start(); // t3 will start only when t2 dies..
But the above approach is not good. Because for other thread to start, previous thread
needs to die. In practice We should think of creating threads as an expensive operation
and try to reuse.
The real problem often is like this, You have to execute tasks T1 , T2 , T3 , T4
sequentially but in different Threads T1 && T3 have to run on one threads and T2 and T4
have to run on another.
So here we can use Two threads instead of 4.
Thread1 will run T1 and then Thread2 will run T2 and then Thread1 will run T3 and so on
i.e.
Thread1 -> T1
Thread2 -> T2
Thread1 -> T3
Thread2 -> T4
All task will be executed sequentially but using 2 threads only.
You can solve the problem like below
Thread1 ->run {
while(canIrun) {
executeTask(taskQueue1.next());
notifyThread2();
waitForThread2Signal();
}
}
Thread2 -.run {
while(canIrun) {
waitForThread1Signal();
executeTask(taskQueue2.next());
notifyThread1();
}
}
The wait and notify method can be implemented using CyclicBarrier very easily.
What would be the point? You can get the same effect, without the overhead, by just calling run().
You can use ExecutorService#submit(Runnable runnable).get()
Is it possible to call immediately join()?
No it is not as start() returns void . You cannot chain those methods that way. And you need to invoke join() on a Thread object.
Method start belongs to Thread class. It would be like doing this:
Thread thread = new Thread(someRunnableTask);
//This fails to compile, because start returns NOTHING (void). This variable will not be filled with pointer to our thread object.
Thread ourOriginalThreadPointer = thread.start();
//Hence this variable references to nothing, no method can be called.
ourOriginalThreadPointer.join()
The instanciated thread doesn't need to be anonymous. You can do that:
public static void main(String[] args) {
for(int i=0; i<5; i++){
SampleClass sc = new SampleClass();
sc.start();
try {
sc.join();
} catch (InterruptedException e) {
}
}
}

Understanding join() method example

The Java thread join() method confuses me a bit. I have following example
class MyThread extends Thread {
private String name;
private int sleepTime;
private Thread waitsFor;
MyThread(String name, int stime, Thread wa) { … }
public void run() {
System.out.print("["+name+" ");
try { Thread.sleep(sleepTime); }
catch(InterruptedException ie) { }
System.out.print(name+"? ");
if (!(waitsFor == null))
try { waitsFor.join(); }
catch(InterruptedException ie) { }
System.out.print(name+"] ");
And
public class JoinTest2 {
public static void main (String [] args) {
Thread t1 = new MyThread("1",1000,null);
Thread t2 = new MyThread("2",4000,t1);
Thread t3 = new MyThread("3",600,t2);
Thread t4 = new MyThread("4",500,t3);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
In which order are the threads terminated?
What actually confuses you about Thread.join()? You haven't mentioned anything specific.
Given that Thread.join() (as the documentation states), Waits for this thread to die, then t4 will wait for t3 to complete, which will wait for t2 to complete, which will wait for t1 to complete.
Therefore t1 will complete first, followed by t2, t3, and t4.
It would terminate in order t1, t2, t3, t4... join causes the currently executing thread to wait until the thread it is called on terminates.
There is a main thread which starts the four customs threads you created t1,t2,t3 and t4. Now when join() method is invoked on a thread and no argument(time) is supplied(which makes it 0 by default meaning maximum wait time is forever) then the calling thread will wait for the thread on which join was invoked to terminate.
When t1.start() is called it's corresponding run() method is invoked by the JVM. Since waitsFor argument is null for t1 it will simply terminate by printing it's name. Since you are adding sleep t2,t3,t4 would be started by the time t1 completes it's sleep. Now t2 will wait for t1 to terminate as we are calling join on t1 from t2. Similarly t3 will wait for t2 and t4 will wait for t3. So youe execution will go t1->t2->t3->t4.
However if t1 terminates before t2 calls join on it, join will simply return because at that point(when t2 calls join on t1) isAlive() will be false.
Surely the order of thread termination would be from t1, t2, and so on here. May be you will get a clear understanding of join() method in java thread from here also http://findnerd.com/list/view/Java-Thread-Join-Example/4465/

Categories

Resources