Showing posts with label Multithreading in java. Show all posts
Showing posts with label Multithreading in java. Show all posts

Printing ODD/EVEN using 2 threads in java - (By ReentrantLock and Condition)

Already in our earlier post we have have seen how to print ODD EVEN numbers using 2 thread using wait() and notify() and using semaphore in java. Below are the links if have not seen it.

Printing ODD/EVEN using 2 threads in java - (By ReentrantLock and Condition)


Printing ODD/EVEN using wait() and Notify() in java

Printing ODD/EVEN using Semaphore in java

Now lets see how to achieve same logic by 2 threads using ReentrantLock along with Condition. First lets see what is ReentrantLock and Condition?

ReentrantLock Lock?
The ReentrantLock class implements the Lock interface and provides synchronization to the methods while accessing shared resources. The code which manipulates the shared resource is surrounded by calls to lock and unlock method. This gives a lock to the current working thread and blocks all other threads which are trying to take a lock on the shared resource.

Condition?
Conditions (also known as condition queues or condition variables) provide a means for one thread to suspend execution (to "wait") until notified by another thread that some state condition may now be true. Because access to this shared state information occurs in different threads, it must be protected, so a lock of some form is associated with the condition. The key property that waiting for a condition provides is that it atomically releases the associated lock and suspends the current thread, just like Object.wait.

A Condition instance is intrinsically bound to a lock. To obtain a Condition instance for a particular Lock instance use its newCondition() method. Hence here we are going to use 2 conditions like 1 for ODD and another for EVEN


 //Reentrant Lock
 private final Lock aLock = new ReentrantLock(); 
 
 // Condition for ODD block
 private final Condition oddCondition = aLock.newCondition(); 
 
 // Condition for EVEN block
 private final Condition evenCondition = aLock.newCondition();

Simple example to print ODD and EVEN numbers using 2 threads upto 10 using above ReentrantLock and Condition. 


import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/*
 * Printing odd numbers using Odd thread and Even
 * numbers using Even thread but in sequential order
 */
public class OddEvenUsingLockAndCondition {

 public static void main(String[] args) {
  
  OddEvenImpl obj = new OddEvenImpl();
  
  Odd odd = new Odd(obj);
  Even even = new Even(obj);
  odd.start();

  /* *
   * Just starting 2nd thread after
   * a half second
   */
  try {
   Thread.sleep(500);
  } catch (InterruptedException e) {
   e.printStackTrace();
  }
  even.start();
 }
 
}

class OddEvenImpl {
 
 //Reentrant Lock
 private final Lock aLock = new ReentrantLock(); 
 
 // Condition for ODD block
 private final Condition oddCondition = aLock.newCondition(); 
 
 // Condition for EVEN block
 private final Condition evenCondition = aLock.newCondition();
 
 // Variable to print ODD/ EVEN numbers
 private int counter = 1;
 
 /*
  * ODD Block
  */
 public void printOdd() throws InterruptedException {
  while(counter <= 10) {
   try {
    // Getting lock for ODD block
    aLock.lock();
    System.out.println("ODD : "+ counter++);
    // signaling to EVEN condition 
    evenCondition.signal();
    /*
     * Just stopping await once reach counter to 10.
     * Not to odd thread to await indefinitely  
     */
    if(counter < 10) { 
     oddCondition.await();
    }
   }finally {
    aLock.unlock();
   }
  }
 }
 
 /*
  * EVEN Block
  */
 public void printEven() throws InterruptedException {
  while(counter <= 10) {
   try {
    // Getting lock for EVEN block
    aLock.lock();
    System.out.println("EVEN : "+ counter++);
    // signaling to ODD condition 
    oddCondition.signal();
    /*
     * Just stopping await once reach counter to 10.
     * Not to even thread to await indefinitely  
     */
    if(counter < 10) {
     evenCondition.await();
    }
   }finally {
    aLock.unlock();
   }
  }
 }
}

class Odd extends Thread {
 OddEvenImpl pc;
 public Odd(OddEvenImpl pc) {
  this.pc = pc;
 }
 @Override
    public void run() {
        try {
            pc.printOdd();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Even extends Thread {
 OddEvenImpl pc;
 public Even(OddEvenImpl pc) {
  this.pc = pc;
 }
 @Override
    public void run() {
        try {
            pc.printEven();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

OUTPUT:


ODD : 1
EVEN : 2
ODD : 3
EVEN : 4
ODD : 5
EVEN : 6
ODD : 7
EVEN : 8
ODD : 9
ODD : 10