Core JAVA
Java Runtime Environment (JRE)
Java Virtual Machine (JVM)
Java overview
Java basics
Java Objects and classes
Java Constructors
Java basic datatypes
Java variable types
Java modifiers/Access Modifiers In Java
Java Basic Operators
Java Loops and Controls
Java conditions
Java numbers and characters
Java strings
Java arrays
Java date time
Java methods
Java file and IO operations
Java exceptions
Inner class
Java OOPs Concepts
Java Inheritance
Java Polymorphism
Java Abstraction
Java Encapsulation
Java Interface
Cohesion and Coupling
Association, Aggregation and Composition
Java Collections
Java ArrayList
Java LinkedList
Set and HashSet
LinkedHashSet and TreeSet
Queue and PriorityQueue
Deque and PriorityQueue
Java Map Interface
Java HashMap
Internal Working Of Java HashMap
Java Mutithread
Methods of Thread In Java
Join , run & Start Method in Threads
Difference b/w start & run Methods in Threads
Java Concurrency Package & its Features
CountDownLatch, CyclicBarrier, Semaphore and Mutex in Thread
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();
   }
}
}