I am trying to understand the code flow with join().
public class Multi extends Thread {
public void run() {
for (int i = 0; i < 5; i++) {
Joins
The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join(); causes the current thread to pause execution until t's thread terminates. Overloads of join allow the programmer to specify a waiting period. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.
Like sleep, join responds to an interrupt by exiting with an InterruptedException.
How does
join()
work in java?
I grant you that the javadoc for join() is a little bit unclear, because it's not obvious who this
refers to when you first read it.
It means that the thread calling t.join()
blocks until the thread t
has finished its execution. If t
has already finished when the current thread calls t.join()
, then the current thread does not stop and just keeps going.
The word this
in the doc refers to t
here, not to the thread that calls the method.
Does it guarantee the execution before
main()
?[...] if no join is used,
main()
executes anywhere b/w the execution of threads [...]
You shouldn't consider main()
as a whole. Parts of main()
are executed before the other threads, parts of it in parallel, and parts of it after. That's actually what start()
and join()
control. Let me explain below.
main()
Here is the sequence of events regarding t1.start()
and t1.join()
. You can obviously think the same way for t3
.
The instructions of main()
preceding t1.start()
are executed
t1.start()
starts the thread t1
(t1.run()
might not start right away.)
The instructions of main()
between t1.start()
and t1.join()
are executed in parallel(*) of the ones in t1.run()
.
Note: You have none in your example, so only t1.run() instructions are executed at this moment.
t1.join()
:
t1.run()
has already finished, nothing happens and main()
keeps goingt1.run()
has not finished yet, the main thread stops and waits until t1.run()
finishes. Then t1.run()
finishes, and then main()
resumes.The instructions of main()
after t1.join()
are executed
Here you can see that:
main()
preceding t1.start()
is guaranteed to be executed before t1.run()
main()
following t1.join()
is guaranteed to be executed after t1.run()
(*) see below section about parallelism
Suppose you have these 2 sets of instructions being executed in 2 threads A and B:
// Thread A | // Thread B
|
System.out.println("A1"); | System.out.println("B1");
System.out.println("A2"); | System.out.println("B2");
System.out.println("A3"); | System.out.println("B3");
If these 2 threads are "executed in parallel", this means 3 things:
the order of execution of the instructions of thread A is guaranteed:
A1 will execute before A2, and A2 before A3.
the order of execution of the instructions of thread B is guaranteed:
B1 will execute before B2, and B2 before B3.
however, A's and B's instructions can be interlaced, which means all of the following are possible (and more):
A1, B1, A2, B2, B3, A3
B1, B2, A1, B3, A2, A3
A1, A2, A3, B1, B2, B3 // special case where A's are all executed before B's
B1, B2, B3, A1, A2, A3 // special case where B's are all executed before A's
Note: this section dealt with parallelism as an illusion created by the OS to make the user feel like things run at the same time, where actually there is only one core executing instructions sequentially, jumping from one process/thread to another.
In fact, an A instruction and a B instruction could be executed simultaneously (real parallelism) on 2 separate cores. The 3 bullet points above still stand anyway. As @jameslarge pointed out, usually we model concurrency with a sequence of events, even for multicores. This leaves aside the concept of simultaneity of 2 events, which does not bring anything useful but complications.