Java program to print odd and even numbers using two threads and wait-notify synchronization
Introduction
In this tutorial, we will learn to print odd and even numbers sequentially using two threads. Like odd thread should print odd numbers and even thread should print even numbers in sequential order. For this two threads should communicate with each other which is called inter-thread communication
Approach
We need two threads one for printing odd numbers and the other for printing even numbers. Thread can implemented either by extending thread class or implementing the runnable interface.
Inside the run method, we will run the code until max number and to print even or odd numbers
Below is the code for two threads t1 and t2, in which t1 prints odd numbers and t2 prints even numbers
1public class OddEvenPrinterByTwoThreads {23 public static void main(String[] args) {4 int max = 10;56 Thread t1 = new Thread(() -> {7 for (int i = 1; i <= max; i = i + 2) {8 System.out.println(Thread.currentThread().getName() + ": " + i);9 }10 }, "T1");1112 Thread t2 = new Thread(() -> {13 for (int i = 2; i <= max; i = i + 2) {14 System.out.println(Thread.currentThread().getName() + ": " + i);15 }16 }, "T2");1718 t1.start();19 t2.start();20 }21}
The above code produces the sample output as below :
1 T2: 22 T1: 13 T1: 34 T1: 55 T1: 76 T2: 47 T1: 98 T2: 69 T2: 810 T2: 10
If we run the same program again, it might show different output, as here two threads started and they start executing their task which is not in control.
But we should print the numbers in sequential order as 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
To achieve this, we should make both threads communicate with each other and print in proper order. For this we use methods wait() and notify() or notifyAll() in synchronized block. As here we always need to wake up either t1 or t2, notify() method is sufficient to use.
Now Lets write methods for printing even or odd now, by using wait() and notify.
- Define a flag called "evenFlag" which is used to determine which thread to print at any point of time.
- The flag should be volatile to make sure, always threads read the correct value as the value gets updated.
- To make sure to print number 1 first, we should give chance to oddNumber printer thread "T1" so for this we will set evenFlag value to false.
- When T2 thread gets chance, In printEven() method, we wait if the number is odd in an infinite loop, by calling wait() method. Once the while loop condition is false, we print number and update the evenFlag to false and call notify() method which wakes up thread T1.
1public volatile boolean evenFlag = false;23public void printEven(int number) {4 synchronized (this) {5 while (!evenFlag) {6 try {7 this.wait();8 } catch (InterruptedException e) {9 e.printStackTrace();10 }11 }12 System.out.println(Thread.currentThread().getName() + "->" + number);13 evenFlag = false;14 this.notify();15 }16}
- Same way we write printOdd method which is being processed by thread T1
1public void printOdd(int number) {2 synchronized (this) {3 while (evenFlag) {4 try {5 this.wait();6 } catch (InterruptedException e) {7 e.printStackTrace();8 }9 }10 System.out.println(Thread.currentThread().getName() + "->" + number);11 this.notify();12 evenFlag = true;13 }14}
Code Implementation
1public class OddEvenPrinterUsingWaitAndNotify {23 public volatile boolean evenFlag = false;45 public static void main(String[] args) {6 int max = 20;7 OddEvenPrinterUsingWaitAndNotify obj = new OddEvenPrinterUsingWaitAndNotify();89 Thread t1 = new Thread(() -> {10 for (int i = 1; i <= max; i = i + 2) {11 obj.printOdd(i);12 }13 }, "T1");14 Thread t2 = new Thread(() -> {15 for (int i = 2; i <= max; i = i + 2) {16 obj.printEven(i);17 }18 }, "T2");1920 t1.start();21 t2.start();22 }2324 public void printEven(int number) {25 synchronized (this) {26 while (!evenFlag) {27 try {28 this.wait();29 } catch (InterruptedException e) {30 e.printStackTrace();31 }32 }33 System.out.println(Thread.currentThread().getName() + "->" + number);34 evenFlag = false;35 this.notify();36 }37 }3839 public void printOdd(int number) {40 synchronized (this) {41 while (evenFlag) {42 try {43 this.wait();44 } catch (InterruptedException e) {45 e.printStackTrace();46 }47 }48 System.out.println(Thread.currentThread().getName() + "->" + number);49 this.notify();50 evenFlag = true;51 }52 }53}