Java CyclicBarrier Tutorial 🎯

beginner
15 min

Java CyclicBarrier Tutorial 🎯

Welcome to our Java CyclicBarrier tutorial! In this lesson, we'll learn about the CyclicBarrier class, a powerful synchronization tool in Java that helps coordinate threads. Let's dive in!

What is a CyclicBarrier? 📝

A CyclicBarrier is a synchronization tool that allows a group of threads to all pause and wait at a certain point in their execution, and then continue when all threads have reached the barrier. It's called "cyclic" because it can be reused after the threads have all passed through it, unlike the CountDownLatch.

When to use a CyclicBarrier? 💡

CyclicBarrier is useful in scenarios where multiple threads are working independently on some task, and they need to synchronize at certain points to achieve a common goal. For example, in a multi-threaded application where threads are processing data in parallel, but they need to wait for all threads to finish processing before moving on to the next phase.

Creating a CyclicBarrier ✅

To create a CyclicBarrier, you'll need to use the CyclicBarrier constructor and pass the number of parties (threads) as an argument.

java
import java.util.concurrent.CyclicBarrier; CyclicBarrier barrier = new CyclicBarrier(numOfThreads);

In the above code, numOfThreads is the number of threads participating in the barrier.

Using a CyclicBarrier 📝

Each thread calls the await() method when it reaches the barrier. This method blocks the thread until all other threads have also reached the barrier, and the barrier's reset flag is set to false.

After all threads have reached the barrier, the barrier's reset flag is set to true, and the barrier resets, allowing the threads to continue their execution.

Advanced Example 🎯

Let's consider an example where we have a file-processing application that reads a large file in parallel using multiple threads. Each thread reads a chunk of the file and processes it. However, before we can write the processed data to a new file, we need to ensure that all threads have finished processing their chunks. This is where a CyclicBarrier comes in handy.

Here's a simplified example:

java
import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; public class FileProcessor { private static final String FILE_NAME = "largeFile.txt"; private static final int NUM_THREADS = 4; private static final CyclicBarrier barrier = new CyclicBarrier(NUM_THREADS); public static void main(String[] args) throws Exception { List<Future<String>> futures = new ArrayList<>(); for (int i = 0; i < NUM_THREADS; i++) { Runnable worker = () -> { try { String chunk = readChunkFromFile(FILE_NAME); processChunk(chunk); barrier.await(); } catch (Exception e) { e.printStackTrace(); } }; Thread thread = new Thread(worker); thread.start(); futures.add(thread); } // Wait for all threads to complete for (Future<String> future : futures) { future.get(); } writeProcessedDataToFile(); } private static String readChunkFromFile(String fileName) { // Read a chunk of the file and return it } private static void processChunk(String chunk) { // Process the chunk of data } private static void writeProcessedDataToFile() { // Write the processed data to a new file } }

In this example, we create a CyclicBarrier with the number of threads we're using. Each thread reads a chunk of the file, processes it, and then waits at the barrier using the await() method. After all threads have finished processing their chunks, the writeProcessedDataToFile() method is called to write the processed data to a new file.

Quiz 💡

Quick Quiz
Question 1 of 1

What is a CyclicBarrier used for in Java?