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.