I have read the official documentation and about 25 tutorials, but I'm still struggling with how I might synchronize say, 3 threads with Monitor
Pulse()
and Wait()
methods and using lock
objects.
(Yes, I know there are other techniques of synchronization, but this should be doable and it's frustrating me)
Here's my simple "proof of concept" idea I came up with.
Let's say I have three threads, each with a task:
- Thread1 runs a task that prints out all integers divisible by 3
- Thread2 runs a task that prints out all integers whose remainder is 1 when divided by 3
- Thread3 runs a task that prints out all integers whose remainder is 2 when divided by 3
I'd like ultimately the output to be: 0,1,2,3,4,5,6,... up to whatever integer limit I might choose but we can say 50 or 100 - it doesn't matter.
I'd like to more fully understand the mechanism of lock vs Monitor.Wait() and Monitor.Pulse() and how they can work together.
If I understand correctly, when a thread encounters a lock(someObject) { ... }
, it gains exclusive access to that critical area if it's the first one there. Any other thread that encounters a lock on the same object is stuck on that line (i.e., lock(someObject)
) in its respective code, correct?
If thread 1 has the lock(someObject)
calls Monitor.Wait(someObject)
, then the thread 1 releases the lock and enters the waiting queue, correct? Then if any other thread (e.g., thread 2) calls Monitor.Pulse(someObject)
, it would move the thread1 into the ready queue?
No matter what I try, it seems like the code keeps just waiting/blocking infinitely.
I guess my summary questions are:
- Do I need more than one lock object to synchronize three threads using
Pulse
andWait
? - Where would the
Wait
andPulse
go in this code? Inside a lock around the loop that is being used to iterate over the values that we want to print? Inside a lock, placed only inside a condition (e.g.,if (i % 3 == 2)
) ? Etc.
I'm thankful for any helpful input!
UPDATE (8/7/2021):
It turns out making the locks static was necessary given the way I had it set up in a single file. I'm irritated that I didn't notice that earlier, but the online documentation suggested (from the Website of Joe Albahari) was immensely helpful.