I\'m confused in join()
method used in Threads in Java. In the following code:
// Using join() to wait for threads to finish.
class NewThread im
First of all, when you create ob1
then constructor is called and it starts execution. At that time t.start()
also runs in separate thread. Remember when a new thread is created, it runs parallely to main thread. And thats why main start execution again with next statement.
And Join()
statement is used to prevent the child thread from becoming orphan. Means if you did'nt call join()
in your main class, then main thread will exit after its execution and child thread will be still there executing the statements. Join()
will wait until all child thread complete its execution and then only main method will exit.
Go through this article, helps a lot.
I'm not able to understand the flow of execution of the program, And when ob1 is created then the constructor is called where t.start() is written but still run() method is not executed rather main() method continues execution. So why is this happening?
This depends on Thread Scheduler as main shares the same priority order. Calling start() doesn't mean run() will be called immediately, it depends on thread scheduler when it chooses to run your thread.
join() method is used to wait until the thread on which it is called does not terminates, but here in output we see alternate outputs of the thread why??
This is because of the Thread.sleep(1000) in your code. Remove that line and you will see ob1 finishes before ob2 which in turn finishes before ob3 (as expected with join()). Having said that it all depends on when ob1 ob2 and ob3 started. Calling sleep will pause thread execution for >= 1 second (in your code), giving scheduler a chance to call other threads waiting (same priority).
See the concept is very simple.
1) All threads are started in the constructor and thus are in ready to run state. Main is already the running thread.
2) Now you called the t1.join(). Here what happens is that the main thread gets knotted behind the t1 thread. So you can imagine a longer thread with main attached to the lower end of t1.
3) Now there are three threads which could run: t2, t3 and combined thread(t1 + main).
4)Now since till t1 is finished main can't run. so the execution of the other two join statements has been stopped.
5) So the scheduler now decides which of the above mentioned(in point 3) threads run which explains the output.
Thread scheduler is responsible for scheduling of threads. So every time you run the program, there is no guarantee to the order of execution of threads. Suppose you have a thread object named threadOne and if join() is called on threadOne like this:
then all currently executing threads will be paused until thread1 has finished its execution or terminates.
Consider the following piece of code:
class RunnableSample implements Runnable {
private Thread t;
private String threadName;
public RunnableSample(String name) {
this.threadName = name;
}
public void run() {
try {
for(int i = 4; i >= 1; i--) {
System.out.println(Thread.currentThread().getName() + ", " + i);
Thread.sleep(500);
}
} catch (InterruptedException e) {
System.out.println(threadName + " interrupted");
}
}
public void start() {
if(t == null)
t = new Thread(this, threadName);
t.start();
try {
t.join();
} catch(Exception e) {
System.out.println(e);
}
}
}
public class RunnableDemo {
public static void main(String[] args) {
RunnableSample r1 = new RunnableSample("threadOne");
r1.start();
RunnableSample r2 = new RunnableSample("threadTwo");
r2.start();
RunnableSample r3 = new RunnableSample("threadThree");
r3.start();
}
}
The output of the above program will be:
threadOne, 4
threadOne, 3
threadOne, 2
threadOne, 1
threadTwo, 4
threadTwo, 3
threadTwo, 2
threadTwo, 1
threadThree, 4
threadThree, 3
threadThree, 2
threadThree, 1
Since join() is called on threadOne first, threadTwo and threadThree will be paused until threadOne terminates. (NOTE that threadOne, threadTwo and ThreadThree all have started). Now the threads are executing in a specific order. If join() is not called on a thread in our example, then there will be no order of execution of threads.
public void start() {
if(t == null)
t = new Thread(this, threadName);
t.start();
}
Its output will be:
threadOne, 4
threadThree, 4
threadTwo, 4
threadTwo, 3
threadThree, 3
threadOne, 3
threadOne, 2
threadThree, 2
threadTwo, 2
threadOne, 1
threadThree, 1
threadTwo, 1
Coming to synchronization, which is useful if you want to control the access of multiple threads on any shared resource. If you want to restrict only one thread to access shared resources then synchronization is the best way to do it.
My Comments:
When I see the output, the output is mixed with One, Two, Three which are the thread names and they run simultaneously. I am not sure when you say thread is not running by main method.
Not sure if I understood your question or not. But I m putting my answer what I could understand, hope it can help you.
1) Then you created the object, it called the constructor, in construct it has start method which started the thread and executed the contents written inside run() method.
So as you created 3 objects (3 threads - one, two, three), all 3 threads started executing simultaneously.
2) Join and Synchronization They are 2 different things, Synchronization is when there are multiple threads sharing a common resource and one thread should use that resource at a time. E.g. Threads such as DepositThread, WithdrawThread etc. do share a common object as BankObject. So while DepositThread is running, the WithdrawThread will wait if they are synchronized. wait(), notify(), notifyAll() are used for inter-thread communication. Plz google to know more.
about Join(), it is when multiple threads are running, but you join. e.g. if there are two thread t1 and t2 and in multi-thread env they run, the output would be: t1-0 t2-0 t1-1 t2-1 t1-2 t2-2
and we use t1.join(), it would be: t1-0 t1-1 t1-2 t2-0 t2-1 t2-2
This is used in realtime when sometimes you don't mix up the thread in certain conditions and one depends another to be completed (not in shared resource), so you can call the join() method.
when ob1 is created then the constructor is called where "t.start()" is written but still run() method is not executed rather main() method is executed further. So why is this happening?
here your threads and main thread has equal priority.Execution of equal priority thread totally depends on the Thread schedular
.You can't expect which to execute first.
join() method is used to wait until the thread on which it is called does not terminates, but here in output we see alternate outputs of the thread why??
Here your calling below statements from main thread.
ob1.t.join();
ob2.t.join();
ob3.t.join();
So main thread waits for ob1.t
,ob2.t
,ob3.t
threads to die(look into Thread#join doc).So all three threads executes successfully and main thread completes after that