Increase Java application performance using CountDownLatch

Old No Comments on Increase Java application performance using CountDownLatch 338

Many Java programmers, including myself, often under utilize the potential of Java and produce code which cannot utilize modern systems efficiently.

Concurrency is a major area which many noobs leave unexplored. In fact, concurrency should be used right from the newbie stage so as to get a strong hold on Java’s concurrency mechanism. This will also lead to better, faster programs which utilize the modern multi-core CPUs more properly.

In this post, I will walk you through creating a simple concurrency mechanism using the CountDownLatch class.

I’ll take a simple scenario. Read it carefully and imagine the program flow so that you don’t get lost while looking at the code and figuring out what it is supposed to do.

Suppose you want to create a program which does some compression on the list of files provided via the command line arguments. Since the compression algorithms operate independently for individual files, you can have one function which contains the algorithm, called by multiple threads, one per file, to compress the file data. So, for N files, you will be creating N threads and thus processing all files in much less time as compared to compressing all files sequentially (depends upon the number of CPU cores and load on each core). Fast enough, isn’t it?

Now let us go over to how this will be achieved. As I previously mentioned, we will be using CountDownLatch class to synchronize the threads. A CountDownLatch is very similar to a count down timer, except that it has to be counted down explicitly. So here’s a briefing of the steps:

  1. Instantiate a CountDownLatch object in main method with the number of files to be compressed.
  2. Spawn a new thread for each file compression task, passing the file name and CountDownLatch object to each thread, and then start the thread.
  3. Once the thread has finished its task (compression), have it decrement the CountDownLatch counter before destroying itself.
  4. At the end of main function, wait for CountDownLatch to hit zero, after which the program ends.

This way, you ensure that the main function doesn’t end before the threads do, and avoid the risk of running zombie/orphaned threads.

We will create a main class, a compression class and a worker class which will handle the pre-processing and post-processing (if any) and decrement the CountDownLatch. This example code is only dummy and serves only to illustrate how you would go about to use CountDownLatch for multi-threaded Java applications.

Now, keeping the scenario in mind, you should comfortably understand the code. So let the show begin!

Starting with the core class, named Codec, consists of only one static method to compress with file name as a parameter:

public class Codec
{
  public static void compress(String fileName)
  {
    // Compression code which will typically save compressed output to a file.
  }
}

Then comes the worker class, named CodecWorker, implementing the Runnable interface so that a its thread can be created. Notice the countDown() method:

import java.util.concurrent.CountDownLatch;
public class CodecWorker implements Runnable
{
  private final String fileName;
  private final CountDownLatch latch;

  public CodecWorker(String fileName, CountDownLatch latch)
  { this.fileName=fileName; this.latch=latch; }

  @Override
  public void run()
  {
    // Pre-processing code...
    System.out.println("Compressing "+fileName);

    Codec.compress(fileName);

    // Post-processing code...
    System.out.println(fileName+" compressed");

    // Decrement the counter to signal main() that it has finished.
    latch.countDown();
  }
}

Finally, the main class, named CodecMain, parsing the command line arguments creating new worker threads to finish as soon as possible.

Notice the await() method, which blocks the main thread from finishing and exiting before the other worker threads do:

import java.util.concurrent.CountDownLatch;
public class CodecMain
{
  public static void main(String args[])
  {
    // Instantiate CountDownLatch with the number of files to be compressed.
    CountDownLatch latch=new CountDownLatch(args.length);

    // Spawn a new thread for each file compression task.
    for(String arg:args)
      new Thread(new CodecWorker(arg, latch)).start();

    // Wait for CountDownLatch to hit zero.
    try { latch.await(); }
    catch(InterruptedException e)
    { System.err.println("ERROR: Main thread interrupted."); }

    System.out.println(args.length+" files processed.");
  }
}

All the classes are organized as public, so remember to put each one in a different file and then compile and run. Feel free to play around with it. This is just one of the methods in concurrency Java has to offer. Some others include fork/join, scheduled thread pool executor (STPE), future tasks, etc. This method is very easy to understand and I recommend it for all beginner as well as intermediate Java programmers, or anyone who is new to Java concurrency.

A final note to be considered. The above content only describes how to use the CountDownLatch to manage multiple threads. You might have noticed that threads are being created without considering the number of CPU cores, which is not recommended, as too many threads increase thread switching overhead.

Use the following method call to determine the number of CPU cores available to the JVM and accordingly create threads:

Runtime.getRuntime().availableProcessors();

Use a LinkedTransferQueue (java.util.concurrent) to create a queue of worker threads ready to execute and then start as many threads by pulling out the workers from the transfer queue as there are available CPU cores, looping until the latch hits zero by using getCount() method on the latch. Maybe I’ll write a post illustrating this soon.

Happy Coding!

Author

Vivek Prajapati

A moderate level programmer interested in administration and Arduino. Familiar with C++, Java, PHP, C# with my favourite being C++. Just finished my bachelor's degree in IT.

Related Articles

Leave a comment

Back to Top