Have you ever used synchronization primitives in multithreading? Tell me about CountDownLatch, CyclicBarrier, Phaser, and others.
sobes.tech AI
Answer from AI
In multithreaded programming, synchronization primitives help coordinate thread work and manage their interactions.
CountDownLatch is a counter that allows one or more threads to wait until other threads complete a certain number of operations. For example, if you have 3 threads that need to finish preparation, and the main thread waits for their completion, then CountDownLatch is initialized with the value 3, and each thread calls countDown() upon finishing. The main thread calls await() and blocks until the counter reaches 0.
CyclicBarrier is a barrier that makes a group of threads wait for each other until all reach a certain point. After that, the barrier resets and can be reused. This is useful for synchronizing phases of thread work.
Phaser is a more flexible primitive that combines the capabilities of CountDownLatch and CyclicBarrier. It allows dynamically adding and removing participants and supports multiple synchronization phases.
Example of using CountDownLatch in Java:
CountDownLatch latch = new CountDownLatch(3);
Runnable task = () -> {
// Perform task
System.out.println(Thread.currentThread().getName() + " is ready");
latch.countDown();
};
new Thread(task).start();
new Thread(task).start();
new Thread(task).start();
latch.await(); // Wait until all three threads call countDown
System.out.println("All threads are ready, continuing work");
Other primitives include semaphores for limiting the number of threads working simultaneously, and mutexes for mutual exclusion access to resources.