CountDownLatch and Java 8 Functional Interfaces Explained

CountDownLatch – Coordinating Multiple Threads

CountDownLatch is a synchronizer that lets one or more threads pause until a set of operations running in other threads complete. The latch is initialized with a positive count; each worker thread invokes countDown() exactly once when it finishes, and the waiting thread calls await() to block until the counter reaches zero.

CountDownLatch doneSignal = new CountDownLatch(3);

Any thread that needs to wait simply executes:

doneSignal.await();   // blocks until counter == 0

Worker threads signal completion with:

doneSignal.countDown();

Complete Example

public class LatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);

        Runnable task = (name, sleep) -> () -> {
            System.out.println(name + " started");
            try {
                Thread.sleep(sleep);
            } catch (InterruptedException ignored) {
            }
            System.out.println(name + " finished");
            latch.countDown();
        };

        new Thread(task.apply("Worker-A", 1000)).start();
        new Thread(task.apply("Worker-B", 2000)).start();
        new Thread(task.apply("Worker-C", 3000)).start();

        latch.await();
        System.out.println("All workers completed – main thread proceeds.");
    }
}

Lambda Expressions in Java 8

A lambda is a concise way to implement a single-method interface (a functional interface). Syntax:

(parameters) -> expression

or

(parameters) -> { statements; }

Example: a two-argument addition function

BinaryOperator<Integer> add = (x, y) -> x + y;
int sum = add.apply(2, 3);   // 5

Functional Interfaces

These are interfaces annotated with @FunctionalInterface and containing exactly one abstract method. Common ones supplied by java.util.function:

  • Runnable – no-arg, void
  • Callable<T> – no-arg, returns T
  • Consumer<T> – takes T, returns void
  • Supplier<T> – no-arg, returns T
  • Function<T,R> – takes T, returns R
  • Predicate<T> – takes T, returns boolean
  • Comparator<T> – compares two T instances

Function Example

Function<String, Integer> lengthFn = String::length;
int len = lengthFn.apply("Hello");   // 5

Comparator Example

class Person {
    private final String name;
    private final int age;
    Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public int getAge() { return age; }
    public String toString() { return name + " (" + age + ")"; }
}

List<Person> people = List.of(
        new Person("Alice", 25),
        new Person("Bob", 20),
        new Person("Charlie", 30)
);

people.sort(Comparator.comparingInt(Person::getAge));
people.forEach(System.out::println);   // Bob (20), Alice (25), Charlie (30)

Predictae Example

Predicate<Integer> isEven = n -> n % 2 == 0;
System.out.println(isEven.test(4));   // true

Tags: CountDownLatch Java Concurrency Lambda Expressions Functional Interfaces comparator

Posted on Sun, 01 Nov 2026 16:20:04 +0000 by pmiller624