There are three threads in your program, the main, the b1
and the b2
.
The main thread starts the program by creating the other two. Note that the main thread invokes the constructor for the object b1
. The fact of b1
inherit from Thread
is unrepentant up to this point, it will only make a difference when the start()
is called. So far, b1
is just an object like any other. Therefore, who will execute the sleep(1000)
of the builder of b1
is the main thread. The same goes for b2
.
Only after these two sleep
is that the Start!
will appear on the console and it will start the thread b1
for real. A thread b1
will execute your method run()
.
The method interrupt()
asks another thread to stop, but does not wait for it to actually stop. Already the method join()
wait for the other thread to stop, but don’t ask it to stop. To do both, you would have to call for each thread interrupt()
followed by join()
. It happens that in the b1
you just call the interrupt()
and in the b2
you just call the join()
. Therefore, the main thread will ask for the b1
stop, but will not wait for it to stop, while it will not ask the b2
stop but will wait for it to stop. After all this, the main thread will make a sleep(1000)
after waiting for the end of b2
, but without ensuring that b1
is over.
This code demonstrates that you should not be understanding how the flow works when there are multiple threads. Basically, it is as follows:
The thread that starts to execute a method is always the same that ends it. There is nothing in the Java language that allows one thread to start executing one method and another to finish it. This means that everything inside the main
is executed by the main thread.
All method calls and constructs that are within another method executed by a given thread will also be executed by that same thread. This means the thread that executes the method main
, by invoking the constructor of Boat
, will itself execute this constructor, since everything that is within the method main
will be run by the main thread.
A thread is only actually started by invoking the method start()
and the execution of the new thread starts in the method run()
corresponding. This means that the thread that runs the constructor is not the same that will be running the run()
. It also means that before start()
to be invoked, the object representing the thread is just a Java object like any other with nothing special.
Note that once start()
and run()
are different methods, rule 2 above is not violated. The main thread executes the start()
, but who executes the run()
is the thread created.