Click here to Skip to main content
15,904,494 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi,

Wanted to know if my threads in the illustration below are sharing the same queue and lock:

[code]
C#
class ThreadCls
{
   Queue q = new Queue();
   Threads[] t = new Threads[4];
   object sync = new Object();
   EventWaitHandle ewh = new AutoResetEvent(false);
   
   ThreadCls()
   {
      for(int i = 0; i < 4; i++)
      {
          t[i] = new Thread(doWork);
          t.Start();
      }
   }

   public void getData(object data)
   {
      lock(sync)
      {
          q.Enqueue(data);
      }
      ewh.Set();
   }
   public void doWork()
   {
      while(true)
      {
          lock(sync)
          {
              object o = q.Dequeue();
          }
              // processing logic...
              // etc...

         ewh.WaitOne();
      }
   }
}
Posted
Updated 24-Nov-11 19:08pm
v3
Comments
Sergey Alexandrovich Kryukov 25-Nov-11 1:29am    
I voted 4 (I rarely vote that high for questions :-)): it's basically a right way to do things, but you have some problems I tried to explain in my answer.
--SA

1 solution

The question is pointless. Of course, if you put four threads and the lock and the queue in one class and made them private, which is good, the lock and queue are shared. What to ask about?

I must say, you go in the right direction. I can see three problems:

First, the number 4 is hard-coded and used in two places, which is not supportable: what if you want to change it? You might change is in one place, forget in another one, etc. Always avoid any immediate constants like this 4, use explicit constant defined only in one place for whole solution. But why making it a constant at all? Better yes, abstract it out, make it a parameter of the class. (Also bad name for a class: never use abbreviations).

Second problem: data type object is bad. It will need type casts, which is bad. Make your class generic with data type made a generic parameter.

Third problem: lock is redundant. You need only the event wait handle. In many situation, you can even get a deadlock just because of combination of lock and other synchronization primitives. There is also a well-known idea: over-synchronization is always bad. Some inquirers here asked some question about there solution where they synchronized threads so heavily that they made them completely sequential! Always synchronize exactly as much as needed.

Now, I can offer you two solutions I published here at CodeProject, both very close to your approach but made more accurately. First is a wrapper for the thread (which is I think is a must: using a "bare" thread is bad by many reasons I explain in my solution); another one is generic class for a blocking queue which you can transparently use between threads without any other synchronization primitives.

See:
How to pass ref parameter to the thread[^] (thread wrapper),
change paramters of thread (producer) after it started[^] (thread wrapper example with lock),
Simple Blocking Queue for Thread Communication and Inter-thread Invocation[^].

Good luck,
—SA
 
Share this answer
 
v2
Comments
d.allen101 25-Nov-11 1:39am    
SA I understand what you're telling in the first two solutions but I'm not clear on the third problem. I though I had to lock the queue in both locations to prevent a race condition
Nickos_me 25-Nov-11 2:28am    
Excellent answer.
D K N T H 25-Nov-11 3:30am    
awesome SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900