August 21, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Simple Thread Control With Java's CountDownLatch

  • November 27, 2007
  • By Jeff Langr
  • Send Email »
  • More Articles »

The CountDownLatch is a simplified mechanism that allows waiting on a fixed number of threads to complete. It was introduced as part of the Java 5 concurrency API as one of a number of constructs designed to make multithreading code simpler and safer.

I test drove the development of a LineCounter class, as an example class to be used in the context of a multithreaded server. The purpose of this class is to calculate the number of source lines within a file. It's reasonably trivial code. The tests are shown in Listing 1; the source for LineCounter is in Listing 2. LineCounter supports threading via implementing the Runnable interface, but most of the tests have nothing to do with threading. They instead directly interact with the run method.

Listing 1: LineCounterTest.

import static org.junit.Assert.*;
import java.io.*;
import org.junit.*;

public class LineCounterTest {
   private BufferedReader reader;

   @Test
   public void returns0WhenEmpty() {
      write("");
      assertEquals(0, count());
   }

   @Test
   public void returns1WhenOneLine() {
      write("a");
      assertEquals(1, count());
   }

   @Test
   public void returns2WhenTwoLines() {
      write("a\na");
      assertEquals(2, count());
   }

   @Test
   public void returnsNForNLines() {
      write("a\nb\nc");
      assertEquals(3, count());
   }

   @Test
   public void countsMultipleEmptyLines() {
      write("a\nb\n\nc");
      assertEquals(4, count());
   }

   @Test
   public void handlesEndOfLineAsLastCharacter() {
      write("a\n");
      assertEquals(1, count());
   }

   @Test
   public void resetsCountOnException() {
      reader = new BufferedReader(new StringReader(" ") {
      }) {
         @Override
         public String readLine() throws IOException {
            throw new IOException();
         }
      };
      assertEquals(LineCounter.NOT_CALCULATED, count());
   }

   private void write(String contents) {
      reader = new BufferedReader(new StringReader(contents));
   }

   private int count() {
      LineCounter counter = new LineCounter(reader);
      counter.run();
      return counter.getCount();
   }

   @Test
   public void supportsFiles() throws IOException {
      File temp = File.createTempFile("LineCountTest", ".txt");
      BufferedWriter writer = null;
      try {
         writer = new BufferedWriter(new FileWriter(temp));
         writeLine(writer, "a");
         writeLine(writer, "b");
         writer.close();
         LineCounter counter = new LineCounter(temp);
         counter.run();
         assertEquals(2, counter.getCount());
      }
      finally {
         writer.close();
         temp.delete(); // risky!
      }
   }

   @Test(expected = FileNotFoundException.class)
   public void failsConstructionOnFileNotFound()
      throws FileNotFoundException {
      File unlikelyFile = new File("zzzzznotexisting");
      assertFalse(unlikelyFile.exists());
      new LineCounter(unlikelyFile);
   }

   @Test
   public void supportsMultithreading()
      throws InterruptedException {
      write("a\nb\nc");
      LineCounter counter = new LineCounter(reader);
      Thread thread = new Thread(counter);
      thread.start();
      thread.join();
      assertEquals(3, counter.getCount());
   }

   private void writeLine(BufferedWriter writer, String text)
      throws IOException {
      writer.write(text);
      writer.newLine();
   }
}




Page 1 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel