In multi-threaded programming, it’s common for threads to synchronize their work to achieve a common goal. C# provides two classes, Barrier and CountdownEvent, that help threads coordinate their work and synchronize their progress.
Read Also-Concurrent Collections in C#
Barrier Class in C#
The Barrier class in C# is used to synchronize multiple threads at a specific point in the execution of a program. It enables multiple threads to wait for each other to reach a certain point before proceeding to the next step. A Barrier object takes an integer count in its constructor, which is the number of threads that will be synchronized. Each thread must call the Barrier.SignalAndWait method to indicate that it has reached the synchronization point. When all the threads have signaled, the Barrier object releases them all, allowing them to continue with their work.
Here’s an example of using Barrier to synchronize three threads:
Barrier barrier = new Barrier(3);
Thread thread1 = new Thread(() =>
{
Console.WriteLine("Thread 1 starting");
Thread.Sleep(1000);
Console.WriteLine("Thread 1 reached barrier");
barrier.SignalAndWait();
Console.WriteLine("Thread 1 completed");
});
Thread thread2 = new Thread(() =>
{
Console.WriteLine("Thread 2 starting");
Thread.Sleep(2000);
Console.WriteLine("Thread 2 reached barrier");
barrier.SignalAndWait();
Console.WriteLine("Thread 2 completed");
});
Thread thread3 = new Thread(() =>
{
Console.WriteLine("Thread 3 starting");
Thread.Sleep(3000);
Console.WriteLine("Thread 3 reached barrier");
barrier.SignalAndWait();
Console.WriteLine("Thread 3 completed");
});
thread1.Start();
thread2.Start();
thread3.Start();
barrier.SignalAndWait(); // Wait for all threads to complete
Console.WriteLine("All threads completed");
In this example, the Barrier object is created with a count of 3, indicating that three threads will be synchronized. Each thread calls the Barrier.SignalAndWait method to indicate that it has reached the synchronization point. The main thread also calls SignalAndWait to wait for all the threads to complete. When all the threads have signaled, the Barrier object releases them all, and the program outputs “All threads completed”.
CountdownEvent Class in C#
The CountdownEvent class in C# is used to synchronize multiple threads by waiting for a specified number of signals. It provides a way for one or more threads to wait until a set of operations being performed in other threads have completed. A CountdownEvent object is created with a count indicating the number of signals required to complete. Each thread signals the CountdownEvent object by calling the Signal method, and the waiting thread waits for all the signals to be received by calling the Wait method.
Here’s an example of using CountdownEvent to synchronize three threads:
CountdownEvent countdown = new CountdownEvent(3);
Thread thread1 = new Thread(() =>
{
Console.WriteLine("Thread 1 starting");
Thread.Sleep(1000);
Console.WriteLine("Thread 1 completed");
countdown.Signal();
});
Thread thread2 = new Thread(() =>
{
Console.WriteLine("Thread 2 starting");
Thread.Sleep(2000);
Console.WriteLine("Thread 2 completed");
countdown.Signal();
});
Thread thread3 = new Thread(() =>
{
Console.WriteLine("Thread 3 starting");
Thread.Sleep(3000);
Console.WriteLine("Thread 3 completed");
countdown.Signal();
});
thread1.Start();
thread2.Start();
thread3.Start();
countdown.Wait(); // Wait for all threads to complete
Console.WriteLine("All threads completed");
In this example, the CountdownEvent object is created with a count of 3, indicating that three signals are required to complete. Each thread signals the CountdownEvent object by calling the Signal method after completing its work. The main thread waits
for all the signals to be received by calling the Wait method. When all the signals have been received, the program outputs “All threads completed”.
Differences between Barrier and CountdownEvent
While both Barrier and CountdownEvent can be used to synchronize multiple threads, there are some differences between them.
- Barrier is used to synchronize threads at a specific point in the execution of a program, whereas CountdownEvent is used to wait for a specified number of signals.
- Barrier releases all the threads at once when all of them have signaled, whereas CountdownEvent releases one thread at a time as signals are received.
- Barrier can be reused after all threads have completed, whereas CountdownEvent must be recreated for each use.
Conclusion
The Barrier and CountdownEvent classes in C# provide powerful tools for synchronizing multiple threads in multi-threaded programming. They enable threads to coordinate their work and synchronize their progress, ensuring that all threads are working together to achieve a common goal. While they have some differences in their functionality, both classes are useful for different scenarios and can be used effectively in multi-threaded applications