Thread Synchronization in C# using Monitor.Wait and Pulse
Thread synchronization might sound like a low-level programming detail, but it plays a huge role in real-world systems. Think of a smart building: one system adjusts lighting based on motion (odd events), while another controls temperature (even events). They need to take turns so they don’t get in each other’s way.
Or picture a financial app where buy and sell orders are processed by separate threads. Without coordination, things could go haywire—like double-spending or missed trades.
In this post, we’ll walk through a simple C# example where two threads print odd and even numbers in perfect order using Monitor.Wait and Monitor.Pulse. It’s a small demo with big implications—and we’ll even throw in a flowchart to make it crystal clear.
🧩 Problem Statement
In multithreaded applications, especially those dealing with shared resources or sequential operations, ensuring that threads execute in a controlled and predictable manner is crucial. The challenge is to coordinate two threads so that:
- One prints odd numbers.
- The other prints even numbers.
- The output is strictly in numerical order.
This requires thread synchronization, where each thread waits for its turn and signals the other when it's done. Without proper coordination, the threads may race ahead, print out of order, or even clash while accessing shared data.
🔍 Explanation
To solve this, we use:
✅ Shared Resources
number: A shared counter starting from 1.max: The maximum number to print.lockObj: A synchronization object used to control access.
✅ Two Threads
- Thread 1 (PrintOdd): Responsible for printing odd numbers.
- Thread 2 (PrintEven): Responsible for printing even numbers.
✅ Synchronization Mechanism
We use Monitor.Wait and Monitor.Pulse:
Monitor.Wait(lockObj): Makes the thread wait until it’s signaled.Monitor.Pulse(lockObj): Signals another waiting thread to resume.
✅ Execution Flow
- Each thread acquires the lock.
- It checks whether it’s its turn (odd/even).
- If yes:
- Prints the number.
- Increments the counter.
- Pulses the other thread.
- If no:
- Waits for the other thread to signal.
- The loop continues until the counter exceeds the maximum value.
This ensures that the threads alternate correctly, maintaining the order of output.
Let's understand this from the flowchart

Comments
Post a Comment