Tutorials Hut

Java Concurrency Package And Useful Features: CountDownLatch, CyclicBarrier, Semaphore and Mutex

In this article we will look into Java Concurrency package and useful features and concepts like CountDownLatch, CyclicBarrier, Semaphore and Mutex constructs of java.util.concurrency.* package.

CountDownLatch

CountDownLatch is a class in java concurrency package, it is used to provide a way to count down when threads complete and once the entire countdown is zero or threads are done, we can execute the next thread.

Example:

package threads;
import java.util.concurrent.CountDownLatch;

public class CountDownLatchExample {
public static void main(String[] args) throws InterruptedException {

    CountDownLatch countDownLatch = new CountDownLatch(2);
    Worker t1 = new Worker(countDownLatch);
     Worker t2 = new Worker(countDownLatch);

    new Thread(t1).start();
    new Thread(t2).start();

    countDownLatch.await();
    System.out.println("Main thread executing because countdown latch has reached to 0 and threads have finished tasks");
}
}

class Worker implements Runnable{
CountDownLatch countDownLatch;
public Worker(CountDownLatch countDownLatch) {
    this.countDownLatch = countDownLatch;
}

@Override
public void run() {
    System.out.println("Worker thread, name:"+Thread.currentThread().getName());
    countDownLatch.countDown();
}
}

Output

Worker thread, name:Thread-1
Worker thread, name:Thread-0
Main thread executing because countdown latch has reached to 0 and threads have finished tasks

CyclicBarrier

CyclicBarrier is similar to CountDownLatch but can be reused while CountDownLatch can’t be reused. CyclicBarrier is used to make sure all threads which are using it will complete their task and wait at the barrier until all threads reach the barrier, then all of them can move ahead to the barrier.

This is useful if we want to wait for all threads to finish something at some point and then move ahead together.

Example:

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

public class CyclicBarrierExample {

//Runnable task
private static class MyThread implements Runnable {
    private CyclicBarrier barrier;
    public MyThread(CyclicBarrier barrier) {
        this.barrier = barrier;
       }

    @Override
    public void run() {
        try {
            System.out.println(Thread.currentThread().getName() + " waiting at barrier");
            barrier.await();
            System.out.println(Thread.currentThread().getName() + " crossed barrier");
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } catch (BrokenBarrierException ex) {
            ex.printStackTrace();
        }
    }
}
   public static void main(String args[]) {
   //creating CyclicBarrier with 3 parties, the threads need to wait on barrier untill all threads reach there
    final CyclicBarrier cb = new CyclicBarrier(3, new Runnable(){
        @Override
        public void run(){
            //This task will be executed once all thread reaches at barrier
            System.out.println("All parties reached barrier");
        }
    });

    //starting each thread with barrier
    Thread t1 = new Thread(new MyThread(cb), "t 1");
    Thread t2 = new Thread(new MyThread(cb), "t 2");
    Thread t3 = new Thread(new MyThread(cb), "t 3");

    t1.start();
    t2.start();
    t3.start();
}
}

Output

t 1 waiting at barrier
t 3 waiting at barrier
t 2 waiting at barrier
All parties reached barrier
t 2 crossed barrier
t 3 crossed barrier
t 1 crossed barrier

Semaphore

Semaphore is a concept where we have limited number of resources/permits and if concurrently many jobs want to use the resources, we can give them and in a way that it will stop the thread from taking the resource if limit is reached, and no more resources available, and only will give resource to thread, if it gets back resources from some thread which is done with its task.

It is a way to signal that I(thread) am done, you(next thread) may proceed.

Example of Semaphore Class and Its Methods in Java Concurrency

Semaphore mySemaphore = new Semaphore(1);

acquire() – This method is used to acquire the lock, when a thread enters into some critical shared section of code where a resource may get corrupted due to multiple threads, we use it.

release() – This method is used to release locks from object resources.

Mutex

Mutex means mutual exclusive, to access a critical and shared part of an application we use mutex, mutex provides lock to one thread and once it is done, it will release the lock.

We may implement it using synchronization, lock, monitor or Semaphore of java threading concepts.

Example of Mutex using Semaphore

public class SeriesGeneratorUsingSemaphore extends SeriesGenerator{
private Semaphore mutex = new Semaphore(1);

@Override
public int getNextSequence() {
    try {
      mutex.acquire();
       return super.getNextSequence();
    } catch (InterruptedException e) {
        // exception handling code
    } finally {
        mutex.release();
    }
}
}

Relates Article


















  • Leave a Reply

    Your email address will not be published. Required fields are marked *