Sunday, September 14, 2014

Atomic Operations Introduction

Traditional multi-threading approaches use locks to protect shared resources.  Synchronization objects like Semaphores provide mechanisms for the programmer to write code that doesn't modify a shared resource concurrently. The synchronization approaches block other threads when one of the thread is modifying a shared resource. Obviously blocked threads are not doing meaningful work waiting for the lock to be released.

Atomic operations on the contrast are based on non-blocking algorithms in which threads waiting for shared resources don't get postponed. Atomic operations are implemented using hardware primitives like compare and swap (CAS) which are atomic instructions used in multi-threading for synchronization.

Java Atomic Classes

Java supports atomic classes that support lock free, thread safe programming on single variables. These classes are defined in java.util.concurrent.atomic package. Some of the key classes include AtomicBoolean, AtomicInteger, AtomicLong, AtomicIntegerArray, AtomicLongArray and AtomicReference.

Some of the key APIs for AtomicInteger class include:
  • AtomicInteger() - Creates a new AtomicInteger that can be updated atomically. Initial value is set to 0.
  • AtomicInteger(int value) - Creates a new AtomicInteger with the specified initial value.
  • boolean compareAndSet(int expect, int value) - Atomically set the value if the current value is same as expected value.
  • int getAndSet(int newVal) - Atomically sets to new value and returns old value.
  • int getAndIncrement() - Atomically increments the current value and returns old value.
  • int incrementAndGet() - Atomically increments the current value and returns new value.
  • int getAndAdd(int delta) - Atomically adds the delta to current value and returns old value.
Refer to this link for more details.

Java AtomicInteger Example

In this example we have a producer and consumer acting up on a AtomicInteger counter to get lock free synchronization.

package com.sourcetricks.atomic;

import java.util.concurrent.atomic.AtomicInteger;

public class AtomicOpsExample {

  private static AtomicInteger count = new AtomicInteger(0);
  
  // Producer thread. Counts up the resource.
  private static class ProducerTask implements Runnable {

    @Override
      public void run() {
          for ( int i = 0; i < 10; i++ ) {           
            count.getAndIncrement();
            System.out.println("Counting up");   
          }                
      }     
  }

  // Consumer thread. Counts down the resource.
  private static class ConsumerTask implements Runnable {

    @Override
      public void run() {
          for ( int i = 0; i < 3; i++ ) {            
            count.getAndDecrement();
            System.out.println("Counting down");
          }                
      }     
  }
    
  public static void main(String[] args) {
    Thread producer = new Thread(new ProducerTask());
    Thread consumer = new Thread(new ConsumerTask());
    producer.start();
    consumer.start();   
  }
}

This program produces the following output.

Counting up
Counting up
Counting up
Counting up
Counting up
Counting down
Counting down
Counting down
Counting up
Counting up
Counting up
Counting up
Counting up

Refer to this link for more Java Tutorials.

Exchanger Introduction

Exchanger is a synchronization point in which threads can pair and exchange objects. Exchanger simplifies data exchange between two threads. Exchanger waits till two threads reach the synchronization point and then exchanges the data provided by the threads.

Java Exchanger Class

Java support Exchanger synchronization object. Exchanger is a generic class and support the following key APIs.
  • Exchanger() - Constructor to create the exchanger.
  • public V exchange(V x) - Waits for the partner thread to arrive at the exchange point and then swaps the objects

Java Exchanger Example

In this example, we create in the main() program an Exchanger instance for strings. This Exchanger object is then used to exchange strings between the two threads.

package com.sourcetricks.exchanger;

import java.util.concurrent.Exchanger;

public class ExchangerDemo {

  private static class MyTask1 implements Runnable {

    Exchanger<String> exchanger;
    
    MyTask1(Exchanger<String> exchanger) {
      this.exchanger = exchanger;
    }
    
    @Override
    public void run() {
      String str = null;
      try {
        str = exchanger.exchange("Hello from MyTask1");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("Received in MyTask1 = " + str);
    }
    
  }
  
  private static class MyTask2 implements Runnable {

    Exchanger<String> exchanger;
    
    MyTask2(Exchanger<String> exchanger) {
      this.exchanger = exchanger;
    }
    
    @Override
    public void run() {
      String str = null;
      try {
        str = exchanger.exchange("Hello from MyTask2");
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("Received in MyTask2 = " + str);
    }
    
  }
  
  public static void main(String[] args) {
    
    Exchanger<String> exchanger = new Exchanger<String>();
    
    Thread t1 = new Thread(new MyTask1(exchanger));
    Thread t2 = new Thread(new MyTask2(exchanger));
    t1.start();
    t2.start();
  }
}

This program produces the following output.

Received in MyTask2 = Hello from MyTask1
Received in MyTask1 = Hello from MyTask2

Read other concurrency tutorials from Java Tutorials page.
Saturday, September 13, 2014

CyclicBarrier Introduction

CyclicBarrier is a synchronization object that will release when a given number of threads are waiting on it. CyclicBarrier is initialized with a count that indicates the number of threads that must wait on this barrier. CyclicBarrier is useful in applications where threads needs to wait for each other. 

Java CyclicBarrier Class

Java supports CyclicBarrier synchronization object. Some of the key APIs of CyclicBarrier class are listed below.

  • CycliBarrier(int count) - Constructor that creates CyclicBarrier with a specified count. Indicates the number of threads that must invoke await before the barrier is released.
  • int await() - Waits till all threads have invoked wait on this barrier.
  • int await(long timeout, TimeUnit unit) - Waits until all threadshave invoked await on this barrier, or the specified waiting time elapses.

Java CyclicBarrier Example

In this example we have a short task and a long task. We use a CyclicBarrier object to make the short task to wait till the long task has completed. 

package com.sourcetricks.cyclicbarrier;

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

public class CyclicBarrierExample {

  private static class MyTask1 implements Runnable {
    CyclicBarrier barrier;
    
    MyTask1(CyclicBarrier barrier) {
      this.barrier = barrier;
    }
    
    @Override
    public void run() {
      System.out.println("In MyTask1 ...");
      try {
        Thread.sleep(2000);
        barrier.await();
      } catch (InterruptedException | BrokenBarrierException e) {
        e.printStackTrace();
      }
      System.out.println("Completing MyTask1 ...");
    }
  }
  
  private static class MyTask2 implements Runnable {
    CyclicBarrier barrier;
    
    MyTask2(CyclicBarrier barrier) {
      this.barrier = barrier;
    }
    
    @Override
    public void run() {
      System.out.println("In MyTask2 ...");
      try {
        Thread.sleep(10000);
        barrier.await();
      } catch (InterruptedException | BrokenBarrierException e) {
        e.printStackTrace();
      }
      System.out.println("Completing MyTask2 ...");
    }
  }
  
  public static void main(String[] args) {
    CyclicBarrier barrier = new CyclicBarrier(2);
    Thread t1 = new Thread(new MyTask1(barrier));
    Thread t2 = new Thread(new MyTask2(barrier));
    t1.start();
    t2.start();
  }
}

This program produces the following output.

In MyTask1 ...
In MyTask2 ...
Completing MyTask2 ...
Completing MyTask1 ...

Read other concurrency tutorials from Java Tutorials page.
Tuesday, September 9, 2014

CountDownLatch Introduction

CountDownLatch is a synchronization object that allows a thread to wait till certain events occur in other threads. We can make the current thread to wait until few dependent threads have completed their operation. CountDownLatch starts with a initial count. Thread that needs to wait, blocks until the count reaches to zero. Dependent threads on completing their task start to count down after which all the blocked threads are released.

Java CountDownLatch Class

Java supports CountDownLatch  synchronization object. Some of the key APIs of CountDownLatch class are listed below.
  • CountDownLatch(int count) - Constructor that creates CountDownLatch with a specified count.
  • void await() - Current threads waits till the latch has counted down to zero.
  • boolean await(long timeout, TimeUnit unit) - Causes the current thread to wait till the latch has counted down to zero or the specified timeout has occurred.
  • void countDown() - Decrements the latch count. Releases waiting threads on count reaching zero.

Java CountDownLatch Example

In this example, we create a CountDownLatch object with initial count of two. The main thread creates pre-processing threads and awaits for them to be completed. Once the pre-processing threads complete their tasks they decrement the latch count. Once the latch reaches count of zero then the main thread is released and proceeds to completion.

package cdl;

import java.util.concurrent.CountDownLatch;

public class CDLExample {

  private static class PreProcess1 implements Runnable {

    CountDownLatch cdl = null;
    PreProcess1(CountDownLatch cdl) {
      this.cdl = cdl;
    }
    
    @Override
    public void run() {
      System.out.println("Preprocess1 done");
      cdl.countDown();
    }
  }

  private static class PreProcess2 implements Runnable {

    CountDownLatch cdl = null;
    PreProcess2(CountDownLatch cdl) {
      this.cdl = cdl;
    }
    
    @Override
    public void run() {     
      try {
        Thread.sleep(3000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("Preprocess2 done");
      cdl.countDown();
    }
  }
  
  public static void main(String[] args) {
    CountDownLatch cdl = new CountDownLatch(2);
    try {
      new Thread(new PreProcess1(cdl)).start();
      new Thread(new PreProcess2(cdl)).start();
      System.out.println("Waiting ...");
      cdl.await();
      System.out.println("Completed ...");
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
}

This program produces the following output.

Waiting ...
Preprocess1 done
Preprocess2 done
Completed ...

Read other concurrency tutorials from Java Tutorials page.
Sunday, September 7, 2014

Semaphore Introduction

Semaphore is a synchronization primitive that can be used to ensure that only one thread can access a shared resource at any point of time. Semaphore guards critical sections of the code by providing the necessary signalling and prevents any race conditions. Semaphore controls access to shared resources by using counters. If the value of semaphore i.e. counter is greater than zero then it indicates resources are available and a thread can access the shared resource. If the value of semaphore is zero then no resources are available and access is denied.

Semaphores that  allow any arbitrary value for the counter is called counting semaphores. Semaphores that allow only values 0 and 1 are called binary semaphores.

Java Semaphore Class

Java supports Semaphore synchronization object that can be used to implement semaphore. Some of the key APIs of Semaphore class are listed below.

  • Semaphore(int permits) - Constructor that creates a semaphore with the given number of permits.
  • Semaphore(int permits, boolean fair) - Constructor that creates a semaphore with the given number of permits and fairness. If fairness is true it is ensured that waiting threads are granted a permit in the order they requested access.
  • void acquire() - Acquires one permit. If permit is not granted at the time of call then the invoking thread is suspended.
  • void acquire(int permits) - Acquires the specified number of permits.
  • void release() - Release a permit back to the semaphore.
  • void release(int permits) - Releases specified number of permits back to the semaphore.

Java Semaphore Example

In this example, we create a shared resource i.e. count. There is a producer thread which increments the count. There is a consumer thread which decrements the count. We create a semaphore to synchronize the producer and consumer. Both the threads acquire a permit from the semaphore before executing the critical section. Once completed the thread releases the permit back to the semaphore.

package com.sourcetricks.semaphore;

import java.util.concurrent.Semaphore;

public class SemaphoreExample {

  // Shared resources to be guarded
  private static int count = 0;
  
  // Producer thread. Counts up the resource.
  private static class ProducerThread implements Runnable {

    private Semaphore s = null;
    
    ProducerThread(Semaphore s) {
      this.s = s;
    }
    
    @Override
    public void run() {
      try {
        System.out.println("Producer requesting permit");
        s.acquire();
        System.out.println("Producer gets permit");
        for ( int i = 0; i < 5; i++ ) {
          count = count + 1;
          System.out.println("Counting up");
        }
        Thread.sleep(5000);
        System.out.println("Producer releases permit");
        s.release();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    
  }
  
  // Consumer thread. Counts down the resource.
  private static class ConsumerThread implements Runnable {

    private Semaphore s = null;
    
    ConsumerThread(Semaphore s) {
      this.s = s;
    }
    
    @Override
    public void run() {
      try {
        System.out.println("Consumer requesting permit");
        s.acquire();
        System.out.println("Consumer gets permit");
        for ( int i = 0; i < 5; i++ ) {
          count = count - 1;
          System.out.println("Counting down");
        }
        System.out.println("Consumer releases permit");
        s.release();
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
    
  }
  
  // Main program
  public static void main(String[] args) {
    Semaphore semaphore = new Semaphore(1);
    Thread t1 = new Thread(new ProducerThread(semaphore));
    Thread t2 = new Thread(new ConsumerThread(semaphore));
    t1.start();
    t2.start();
  }
}

This program produces the following output.

Producer requesting permit
Consumer requesting permit
Producer gets permit
Counting up
Counting up
Counting up
Counting up
Counting up
Producer releases permit
Consumer gets permit
Counting down
Counting down
Counting down
Counting down
Counting down
Consumer releases permit

Read other concurrency tutorials from Java Tutorials page.

Contact Form

Name

Email *

Message *

Back to Top