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 wait() and Notify() in java
Printing ODD/EVEN using Semaphore in java
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