Wednesday, December 3, 2008

What does Thread.Join() mean?

Couple of days ago I came across the following question over our local web blog, and following is what I replied.

Question:


[Discuss]: A Threading Query…
Consider the following block of code…

//Csharp code snippet..
Line 1: Thread t = new Thread (Go); // Assume Go is some static method
Line 2: t.Start();
Line 3: t.Join(); // Wait (block) calling thread until thread t ends
//End


- In calling thread at line 1 we created a thread object.
- On Line 2 we started the thread t.
- Then on line 3 we are calling Join() method of Thread t which serves the other way around.
I mean if you think logically t.Join() causes the calling thread to wait untill thread T completes.
The join() method is a busy waiting technique… i.e. The main thread is engaged in a continuous
loop checking for thread t.IsAlive property to be false. t.Join() syntax is also an invalidation of an
important OOP concept, “Encapsulation”… i.e. in t.Join() we are actually blocking Main thread
instead of working on Thread t.

I don’t know how many of you agree that logically it should be the other way around (i.e. One
should be calling Thread.CurrentThread.Join(t) instead of t.Join()).

Any one thinks of a reason why the Thread.Join() method was implemented like this??


ANSWER:

1. t.Join() doesnt block the app, it actually waits for the thread to terminate, the message pumping continues; Does something like waits for IsAlive for the given time span as you said.

2. Thread.Join() is used to assure that the thread has terminated successfully. Join() tells the thread object to wait for some time and see if it has ended. This method changes the state of the calling thread to include ThreadState.WaitSleepJoin, which further means this thread is blocked and no work is going to be done.


http://www.digcode.com/Data/DigCode/Attachments/fbf261b2-4ca7-4459-96fd-ae1046b50b4e/threadstate%5B1%5D.png

3. See following loc.

1. Thread t = new Thread(new ThreadStart(ThreadMethod));
2. t.Start();
3.
4. // Wait for foreground thread to end, for good.
5.
6. t.Join(); //wait, until thread ends.
7.
8. //Cursor at this loc would mean that thread t has terminated successfully.
9. //but what if thread t malfunctions and never ends?

Cursor would come to line 7 only if thread t terminates gracefully.

4. Thread.CurrentThread is used to access the application's main thread.

1. Thread.CurrentThread.Join();//Wait, whole life

The above loc would mean, wait for the application thread to finish, which in most cases it would never occur; Unless for a user interface based app, user closes the app manually.

In fact the following two lines of code are almost same:

1. Thread.CurrentThread.Join (); //calling main thread, the app, wait for good.
2. Thread.Sleep (1000); //static method call, wait for 1 sec.

While cursor would never be able come to the line 2 in the above code; But if we provide the Join(secs) with some time span it would come to line 2 after 5 secs (see following locs).

1. Thread.CurrentThread.Join (5000); //calling main thread, the app.
2. Thread.Sleep (1000); //static method call

With Thread.CurrentThread.Join(1000) message pumping continues while Thread.Sleep(1000) hangs the app since its a static method call.

5. Thread.Join() is more preffered with timeout. And using Join() without a timeout may lead to unexpected results; Most common concern you would come across is what if thread t never ends?

So I prefer using Join() to report un/successful thread termination.

1. //Wait for 10 secs and then report the status.
2. if(!t.Join(10000))
3. Log.Error("Couldnt end thread even after 10 seconds");
4. else
5. Log.Info("Thread terminated successfully");

I believe one would use Thread.CurrentThread.Join(1000) for the application to wait for some time, but I do not see the need, or I should say I have yet to come across a situation where I could use Thread.CurrentThread.Join() without any timeout.

6. Since it is written:
"it should be the other way around (i.e. One should be calling Thread.CurrentThread.Join(t) instead of t.Join())."

I am assuming that the word Join() is somewhat not really self explanatory - and is confusing. It should have been something like t.WaitForThreadToQuit() or t.WaitForThreadEnd() or t.WaitForEnd() or wait for some time and then report; Well... I am not sure about a generic name for that method probably thats why MS came up with the Join() thingy. Just thinking... out loud.

I use to refer to an helpful resource whenever I am stuck into the threads (pun intended). (0:
http://www.albahari.com/threading/ there is also a pdf available there.

I am not sure if this answers the question, I would suggest checkout msdn for more precise information/articles/helps.

1 comment:

  1. Anonymous11:57 AM

    Very well explained!

    ReplyDelete

Related Posts

Popular Posts