Tuesday, June 27, 2023

What is Phaser in Java? When and How to use Phaser? Example Tutorial

In Java, Phaser is a synchronization barrier provided by the java.util.concurrent package. It allows you to coordinate a group of threads to wait for each other at a particular phase before moving forward. Phaser is useful when you have a task that can be divided into multiple subtasks, and you want to ensure that all subtasks have completed a particular phase before proceeding to the next phase. 

Here's an example tutorial on how to use Phaser in Java:


import java.util.concurrent.Phaser;

public class PhaserExample {
    public static void main(String[] args) {
        int numWorkers = 3;
        int numPhases = 4;

        Phaser phaser = new Phaser(numWorkers) {
            @Override
            protected boolean onAdvance(int phase, int registeredParties) {
                // This method is called when all threads arrive at the barrier
                System.out.println("All threads arrived at phase: " + phase);
                return phase >= numPhases - 1; // Terminate the phaser after all phases
            }
        };

        for (int i = 0; i < numWorkers; i++) {
            Thread workerThread = new Thread(() -> {
                for (int phase = 0; phase < numPhases; phase++) {
                    System.out.println("Thread " + Thread.currentThread().getId() +
                            " is starting phase: " + phase);
                    // Do some work for the current phase

                    // Wait for all threads to complete this phase
                    phaser.arriveAndAwaitAdvance();

                    // Continue with the next phase
                }
            });
            workerThread.start();
        }
    }
}

In this example, we create a Phaser with an initial number of workers (threads) set to 3. We define the onAdvance method to be called when all threads arrive at the barrier. In this method, we print a message indicating the phase and check if we've reached the final phase (3 in this case) to terminate the phaser. 

Each worker thread executes a loop for each phase. Within the loop, we perform some work specific to the phase, and then call phaser.arriveAndAwaitAdvance(), which signals that the current thread has reached the barrier and waits for all other threads to arrive at the barrier as well. Once all threads have arrived, they continue with the next phase. 

When you run the above code, you'll see output similar to:


Thread 11 is starting phase: 0
Thread 12 is starting phase: 0
Thread 13 is starting phase: 0
All threads arrived at phase: 0
Thread 11 is starting phase: 1
Thread 12 is starting phase: 1
Thread 13 is starting phase: 1
All threads arrived at phase: 1
Thread 11 is starting phase: 2
Thread 12 is starting phase: 2
Thread 13 is starting phase: 2
All threads arrived at phase: 2
Thread 11 is starting phase: 3
Thread 12 is starting phase: 3
Thread 13 is starting phase: 3
All threads arrived at phase: 3

The example demonstrates how the threads wait for each other at each phase before proceeding. You can use this synchronization mechanism to design parallel algorithms, simulations, or any other scenarios where you need to coordinate the execution of multiple threads.

No comments:

Post a Comment