By dave | November 10, 2013

In this example I show an usage of two more concurrent classes CyclicBarrier and Semaphore; which are both provided in the core Java library. There's a wealth of concurrency classes built directly into the JVM that can really simplify multi-threaded development.

CyclicBarrrier to make threads wait for alignment.

In the example below, I use a cyclic barrier to make several threads wait for alignment. This is a common example where we have many threads and need to wait for all threads to reach a barrier before proceeding:

package com.thecoderscorner.example;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * This class shows the usage of the CyclicBarrier class in the form
 * of a simple three thread example. We wait for all threads to
 * reach the cyclic barrier and then the threads print a log line
 * and exit.
 */
public class CyclicBarrierExample {
    // create a cyclic barrier that will wait for three calls before
    // unlocking
    private static final int NO_OF_THREADS = 3;
    private CyclicBarrier barrier = new CyclicBarrier(NO_OF_THREADS);

    public static void main(String[] args) throws InterruptedException {
        CyclicBarrierExample instance = new CyclicBarrierExample();
        instance.init();
    }

    public void init() throws InterruptedException {
        // create three threads that will call await on the cyclic barrier
        for (int i=0; i<NO_OF_THREADS; ++i) {
            Thread th = new Thread(new MyWorkerThread(), "Worker" + i);
            th.start();

            // to help visualise I add a delay between creation
            Thread.sleep(1000);
        }
    }

    /**
     * Here is the runnable used by the above threads, it just waits for the
     * barrier before proceeding to log a line and exit. Notice that the
     * barrier unlocked log line only occurs after all three threads reach
     * the barrier.
     */
    private class MyWorkerThread implements Runnable {
        @Override
        public void run() {
            System.out.println("Thread started");

            try {
                barrier.await();
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }

            System.out.println("Barrier unlocked");
        }
    }
}

And the output of the above is below, notice that all threads wait at the barrier until the last one reaches there, and then they all proceed.

Thread started
Thread started
Thread started
Barrier unlocked
Barrier unlocked
Barrier unlocked

Process finished with exit code 0

Semaphore limiting threads in a section of code

In this example we use a semaphore to limit the number of threads that can proceed through a section of code, in this case we use a good old sleep to simulate a long lived operation:

package com.thecoderscorner.example;

import java.util.concurrent.Semaphore;

/**
 * This example shows an example usage of a semaphore where three threads
 * are trying to gain access to a semaphore that only has two places. For
 * the sake of this example each thread takes a place and waits one second
 * before releasing the place.  We will see there is only ever two threads
 * that are within the block between acquire and release.
 */
public class SemaphoreExample {
    private static final int DEFAULT_PERMITS = 2;
    private static final int NO_OF_THREADS = 3;
    private Semaphore semaphore = new Semaphore(DEFAULT_PERMITS);
    private void init() {
        for(int i=0; i<NO_OF_THREADS; ++i) {
            Thread th = new Thread(new SemaphoreTestThread());
            th.start();
        }
    }

    /**
     * Each thread will look a few times and attempt to take the semaphore.
     * What we will see is that there will never be more than two threads
     * in the sleep section at once.
     */
    private class SemaphoreTestThread implements Runnable {
        @Override
        public void run() {
            try {
                for(int i=0;i<NO_OF_THREADS;i++) {
                    semaphore.acquire();
                    System.out.println("Semaphore acquired");

                    // only ever two threads here
                    Thread.sleep(1000);

                    semaphore.release();
                    System.out.println("Semaphore released");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        SemaphoreExample example = new SemaphoreExample();
        example.init();
    }
}

And the output of the above, notice that there are only ever two threads in the semaphore

Semaphore acquired
Semaphore acquired
Semaphore released
Semaphore acquired
Semaphore released
Semaphore acquired
Semaphore released
Semaphore acquired
Semaphore released
Semaphore acquired
Semaphore released
Semaphore acquired
Semaphore released
Semaphore acquired
Semaphore released
Semaphore released
Semaphore acquired
Semaphore released

Process finished with exit code 0

Other pages within this category

comments powered by Disqus

This site uses cookies to analyse traffic, serve ads by Google AdSense (non-personalized in EEA/UK), and to record consent. We also embed Twitter, Youtube and Disqus content on some pages, these companies have their own privacy policies.

Our privacy policy applies to all pages on our site

Should you need further guidance on how to proceed: External link for information about cookie management.