Skip to content

Yet another programming solutions log

Sample bits from programming for the future generations.

Technologies Technologies
  • Algorithms and Data Structures
  • Java Tutorials
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Spock Framework Tutorial
  • Spring Framework
  • Bash Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Developer’s Tools
  • Productivity
  • About
Expand Search Form

Java CountDownLatch example

farenda 2015-12-03 0

Problem:

How to use Java CountDownLatch to synchronize one or more tasks? The CountDownLatch is one of the most useful and easy to use classes from java.util.concurrent package. Learn how to use it!

CountDownLatch is basically a counter, designed to work in concurrent environment. It has only a handful of methods:

  • void await()
    Waits until the latch has counted down to zero.
  • boolean await(long timeout, TimeUnit unit)
    Like above, but waits only for given time and returns false when not reached zero.
  • void countDown()
    Decrements the number in the latch. Notifies awaiting threads when reached zero.
  • long getCount()
    Returns current value of latch.

    The latch is created with some counter value, tasks decrease counter’s value down to zero, which signals some other thread that jobs have finished.

Solution:

In the following example we’re going to create two tasks that convert a message concurrently and return the results. A task calls latch.countDown() method after doing its work. The main thread calls latch.await() hence waits until all tasks (2 in our case) decrease the latch. When that happens, the main thread is unblocked and continues its work – printing results.

package com.farenda.java.util.concurrent;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.*;

import static java.util.Arrays.asList;

public class CountDownLatchExample {

    private static abstract class ConverterTask implements Callable<String> {

        private final CountDownLatch latch;
        private String value;

        public ConverterTask(CountDownLatch latch, String value) {
            this.latch = latch;
            this.value = value;
        }

        @Override
        public String call() throws Exception {
            value = convert(value);
            latch.countDown();
            return value;
        }

        protected abstract String convert(String value);
    }

    private static class Lowerer extends ConverterTask {

        public Lowerer(CountDownLatch latch, String value) {
            super(latch, value);
        }

        @Override
        public String convert(String value) {
            return value.toLowerCase();
        }
    }

    private static class Upperer extends ConverterTask {

        public Upperer(CountDownLatch latch, String value) {
            super(latch, value);
        }

        @Override
        public String convert(String value) {
            return value.toUpperCase();
        }
    }

    public static void main(String[] args) throws Exception {
        CountDownLatch latch = new CountDownLatch(2);
        ExecutorService executor = Executors.newCachedThreadPool();

        String message = "Hello, World";
        List<Callable<String>> tasks = asList(
                new Lowerer(latch, message), new Upperer(latch, message));

        System.out.println("Converting message to lowercase and uppercase:");
        List<Future<String>> results = new LinkedList<>();
        for (Callable<String> task : tasks) {
            results.add(executor.submit(task));
        }

        // wait for tasks to finish:
        latch.await();

        System.out.println("Shutting down the executor.");
        executor.shutdown();

        System.out.println("Getting converted results:");
        for (Future<String> result : results) {
            System.out.printf("Converted message: %s%n", result.get());
        }
    }
}

In the example we use Callable, because we want to return results. To see how CountDownLatch behaves change await() to await(long timeout, TimeUnit unit) and comment out call to countDown() method.

And here’s the result of running the above code:

Converting message to lowercase and uppercase:
Shutting down the executor.
Getting converted results:
Converted message: hello, world
Converted message: HELLO, WORLD

IMHO it is one of the most useful classes from Java Concurrent package.

Share with the World!
Categories Java Tags java, java-concurrency
Previous: Top Software Design Books
Next: Flexibly ignore tests in Spock

Recent Posts

  • Java 8 Date Time concepts
  • Maven dependency to local JAR
  • Caesar cipher in Java
  • Java casting trick
  • Java 8 flatMap practical example
  • Linked List – remove element
  • Linked List – insert element at position
  • Linked List add element at the end
  • Create Java Streams
  • Floyd Cycle detection in Java

Pages

  • About Farenda
  • Algorithms and Data Structures
  • Bash Tutorial
  • Bean Validation Tutorial
  • Clojure Tutorial
  • Design Patterns
  • Java 8 Streams and Lambda Expressions Tutorial
  • Java Basics Tutorial
  • Java Collections Tutorial
  • Java Concurrency Tutorial
  • Java IO Tutorial
  • Java Tutorials
  • Java Util Tutorial
  • Java XML Tutorial
  • JUnit Tutorial
  • MongoDB Tutorial
  • Quartz Scheduler Tutorial
  • Software Developer’s Tools
  • Spock Framework Tutorial
  • Spring Framework

Tags

algorithms bash bean-validation books clojure design-patterns embedmongo exercises git gof gradle groovy hateoas hsqldb i18n java java-basics java-collections java-concurrency java-io java-lang java-time java-util java-xml java8 java8-files junit linux lists log4j logging maven mongodb performance quartz refactoring regex rest slf4j solid spring spring-boot spring-core sql unit-tests

Yet another programming solutions log © 2021

sponsored