OBJECTIVE Implement a barrier synchronization object using only the java built-in synchronized, wait(), notifyAll() primitives.

(BY YOURESELF! NO PAIR PROGRAMMING)
DETAILED DESCRIPTION

Barrier synchronization is used when we need a group of threads to all arrive at the same point in a program before continuing to execute. A simple example of why we might want to do this would be to collect execution time statistics. We want all threads to finish initialization before we start timing and all threads to finish computing before stopping the timing. This short example illustrates the use of a barrier:

class Worker extends Thread
{
  Worker(Barrier barrier){...}
  public void run()
  {
    //initialization...
    barrier.await(); //wait for all threads to finish initialization
    //computation...
    barrier.await(); //wait for all threads to finish computing
  }
}

class Driver
{
  public static void main(String[] args)
  {
    int nWorkers = 5;
    Barrier barrier = new Barrier(nWorkers + 1); //N workers plus this thread
    for(i = 0; i < nWorkers; i++)
    {
      (new Worker(barrier)).start();
    }

    barrer.await(); //wait for all workers to initialize
    //start timing
    barrier.await(); //wait for all to finish computing
    //stop timing
  }
}

Barriers are also used for more important synchronization tasks such as coordinating successive computations between threads. For example, computations involving matrices may use barriers if each thread computes one part of the matrix and shares results with its neighbors at each step in order to continue the computation.

Barrier synchronization objects are found in many parallel computing libraries such as Open MPI. Java 1.5 has a CyclicBarrier class located in the java.util.concurrent package that implements barrier synchronization.

Your assignment is to implement a Barrier class that can be used for barrier synchronization. You must also submit JUnit tests for your Barrier class. Note that there are other classes in the java.util.concurrent.* package that can be used to implement more elaborate synchronization methods, but you should only use the allowed primitives mentioned above.

Your class should have at least the following:

  1. a constructor that takes an integer indicating the number of threads that will participate in the barrier.
  2. an await() method that will block a thread until the required number of threads (indicated by the constructor) reach the barrier. When the last thread calls await() all threads should be allowed to continue.
TESTING HINTS To test your Barrier class you need to check that no thread is executing past the barrier until all threads have reached the barrier. Unit tests for concurrent programs can be difficult to write and are an area of active research at Rice. One way to write a test would be to keep a global counter that keeps track of how many threads have reached the barrier. Assert that the counter value is equal to the number of threads once you get past the barrier. Your unit tests should make liberal use of randomness and Thread.sleep()/Thread.yield() in order to test different execution schedules.
SUBMITTINGYou will use the "turnin" script to submit your code.

ALSO YOU MUST INCLUDE A "README.txt" FILE that says (1) how long it took you to complete the homework and (2) how useful you thought the assignment was on a scale of 1 to 10 (10 is the most useful, 1 is busy work).
    turnin -c comp314 -p hw3 files
GRADING Your homework will be graded on the correctness of your implementation and usefulness of your unit tests.
OTHER DOCS:

Last modified: April 11, 2006 01:05