The method
Thread.Sleep
is the static method. No thread reference is passed. So, which thread is sleeping? The calling one.
In contrast to this, the method
Thread.Join
is an instance method. You pass an instance reference to this method. From the view point of the method implementation, the instance is passed as "this", implicit parameter. From the stand point of the caller, you pass an instance of some thread,
other then the calling thread. Having
Thread thread = //...
, you pass the instance of
thread
using the usual syntax
thread.Join()
. This method is a blocking method for a calling thread as well, not the thread
thread
passed to a call. The only difference between
Sleep
and
Join
is the primary condition for waking up of the
calling thread: in first case, this is just timer expiration, in second case, this is the termination of thread
thread
.
In both cases, a calling thread in put in a special wait state: the OS switches it off and never schedule back to execution (so a thread in the wait state waste no CPU time) until it is awaken. I mentioned main ("intended") conditions of waking up. There are other conditions. For
Join(Int32)
or
Join(TimeSpan)
the calling thread is waken up either by termination of the thread passed to the method or expiration time, whichever comes first. Also, any thread will be awaken by
Abort
or
Interrupt
Please see:
http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx[
^].
Everything is well explained here, just read with attention.
Your "no difference" observation proves nothing, as many experiments. You just don't follow proper logic. Your result is easy to explain based on the knowledge of what these methods do. This is simple: the thread calling
Join(Int32)
in your case is awakened always by expiration time and never by the termination of the thread
th
by a
simple reason: 5000 > 3000.
—SA