The preceding code example shows an example of how we can make the flow of our threaded programs somewhat deterministic by utilizing this join method.
We begin by defining a very simple function called myThread, which takes in one parameter. All this function does is print out when it has started, sleep for whatever value is passed into it times 2, and then print out when it has finished execution.
In our main function, we define two threads, the first of which we aptly call thread1, and pass in a value of 1 as its sole argument. We then start this thread and execute a print statement. What's important to note is that this first print statement executes before the completion of our thread1.
We then create a second thread object, and imaginatively, call this thread2, and pass in 2 as our sole argument this time. The key difference, though, is that we call thread2.join() immediately after we start this thread. By calling thread2, we can preserve the order in which we execute our print statements, and you can see in the output that Thread 2 Is Definitely Finished does indeed get printed after thread2 has terminated.