Module 14 of 30 · Java Programming — Core to Enterprise · Intermediate

Concurrency Utilities

Duration: 7 min

This module delves into Java's concurrency utilities, which are essential for developing efficient and responsive applications. Understanding these utilities is crucial for managing multiple tasks simultaneously, optimizing performance, and preventing common concurrency issues such as deadlocks and race conditions.

ExecutorService for Thread Management

ExecutorService is a high-level API for managing threads. It provides methods to submit tasks for execution and retrieve their results. This abstraction simplifies the process of creating and managing threads, allowing developers to focus on task logic rather than thread management.

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ExecutorExample {
    public static void main(String[] args) {
        // Create an ExecutorService with a fixed thread pool of 5 threads
        ExecutorService executor = Executors.newFixedThreadPool(5);

        // Submit tasks to the executor
        for (int i = 0; i < 10; i++) {
            final int taskId = i;
            executor.submit(() -> {
                System.out.println("Task " + taskId + " executed by " + Thread.currentThread().getName());
            });
        }

        // Shutdown the executor
        executor.shutdown();
    }
}
Task 0 executed by pool-1-thread-1
Task 1 executed by pool-1-thread-2
Task 2 executed by pool-1-thread-3
Task 3 executed by pool-1-thread-4
Task 4 executed by pool-1-thread-5
Task 5 executed by pool-1-thread-1
Task 6 executed by pool-1-thread-2
Task 7 executed by pool-1-thread-3
Task 8 executed by pool-1-thread-4
Task 9 executed by pool-1-thread-5

CountDownLatch for Synchronization

CountDownLatch is a utility that allows one or more threads to wait until a set of operations being performed in other threads completes. It is particularly useful for synchronizing threads, ensuring that a thread does not proceed until all threads have finished their tasks.

import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
    public static void main(String[] args) throws InterruptedException {
        // Create a CountDownLatch initialized with a count of 3
        final CountDownLatch latch = new CountDownLatch(3);

        // Create and start three threads
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try {
                    Thread.sleep((int) (Math.random() * 1000));
                    System.out.println(Thread.currentThread().getName() + " completed");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    latch.countDown();
                }
            }).start();
        }

        // Await the completion of all threads
        latch.await();

        System.out.println("All threads completed");
    }
}

💡 Tip: When using CountDownLatch, ensure that the count is set correctly to avoid deadlocks. If the count is not decremented properly, the latch will never be released, causing threads to wait indefinitely.

❓ What is the primary purpose of ExecutorService in Java?

❓ What will happen if the count of CountDownLatch is not decremented properly?

← Previous Continue interactively → Next →

Related Courses