In a multithreaded Java process , it is often needed a communication between different threads. This inter-thread communication is performing using wait(), notify() , and notifyAll() methods of Java.Lang.Object class. The idea is going to be clear once we do an example which has two child threads and those two child threads are communicating with each other.
Communication between threads in Java – Example
Here we are discussing an example which has two threads. One thread is printing even numbers from 0 to 50, while the other thread is printing odd numbers from 0 to 50. Our aim is to print even and odd numbers alternately. The class EvenRunnable.java has the logic in the run() method , to print the even numbers.Similarly the class OldRunnable has the logic to print odd numbers. Let us see the code first.
public class EvenRunnable implements Runnable {
private int number = 2;
private Object shared = null;
public EvenRunnable(Object object) {
shared = object;
}
public void run() {
while (number < 50) {
synchronized (shared) {
System.out.println("Even number = " + number);
number = number + 2;
try {
Thread.sleep(500); //only to view sequence of execution
shared.notify();
shared.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class OddRunnable implements Runnable {
int oddNumber = 1;
private Object shared = null;
public OddRunnable(Object object) {
shared = object;
}
public void run() {
while (oddNumber < 50) {
synchronized (shared) {
System.out.println("Odd number = " + oddNumber);
oddNumber = oddNumber + 2;
try {
Thread.sleep(500); // only to view the sequence of execution
shared.notify();
shared.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Now let us see the main class.
public class Main {
public Main(){
}
public static void main(String[] args) {
Object shared = new Object();
EvenRunnable evenRunnable = new EvenRunnable(shared);
OddRunnable oddRunnable = new OddRunnable(shared);
Thread evenThread = new Thread(evenRunnable, "evenThread");
Thread oddThread = new Thread(oddRunnable, "oddThread");
oddThread.start();
evenThread.start();
}
}
Here we have a common object for these two threads .And only one thread is allowed to access that object at a time . So synchronized block should be there (For more details about synchronized blocks , click here) . Our main method of Main.java creates two threads with names 'evenThread' and 'oddThread' from the Runnable objects.Then start() method of the two threads are calling.Assume 'oddThread' started first and it got the lock on shared object.So 'evenThread' needs to wait to get the lock . Now 'oddThread' prints the value and it sleeps for few moments. Then the shared.notify() will be called after incrementing the odd number by 2 . Then calling wait() method on shared . It releases the lock for 'oddThread' on shared and it is moving to waiting state .Now 'evenThread' is holding the lock . It prints an even number , then sleeping for a moment , then incrementing the number by two .When the 'evenThread' calls the notify() method the 'oddThread' wakes up and when wait() is called for 'evenThread' 'oddThread' is getting lock back on shared . And it prints the next odd number .This process continuous till the number reaches maximum value of 50 . This can be verified the output of our Main.java
Output
Odd number = 1
Even number = 2
Odd number = 3
Even number = 4
Odd number = 5
Even number = 6
Odd number = 7
Even number = 8
Odd number = 9
Even number = 10
Odd number = 11
Even number = 12
Odd number = 13
Even number = 14
Odd number = 15
Even number = 16
Odd number = 17
Even number = 18
Odd number = 19
Even number = 20
Odd number = 21
Even number = 22
Odd number = 23
Even number = 24
Odd number = 25
Even number = 26
Odd number = 27
Even number = 28
Odd number = 29
Even number = 30
Odd number = 31
Even number = 32
Odd number = 33
Even number = 34
Odd number = 35
Even number = 36
Odd number = 37
Even number = 38
Odd number = 39
Even number = 40
Odd number = 41
Even number = 42
Odd number = 43
Even number = 44
Odd number = 45
Even number = 46
Odd number = 47
Even number = 48
Odd number = 49
Summary
Inter-thread communication can be done by three methods of Java.lang.Object class
1)wait() - It releases lock from the current thread and current thread is moving to the waiting state.
2)notify()-It wakes up the first thread that is waiting to get lock on a particular object.It is not releasing the lock.
3)notifyAll() - It wakes up all the threads those are waiting to get lock on a particular object.It is not releasing the lock.
Remember these methods should be called only from a synchronized context.
Pingback: Object class in Java | CoderPanda
Hi when we execute the above code, when the number value becomes more than 50 it will not enter in to the while loop. But before that both the even thread and the odd thread will we in wait state thinking that some other thread will notify and hence a dead lock situation happened here. In order to avoid the deadlock situation please move the while loop inside the synchronized block and try to call notify method after while loop, so that we can avoid the deadlock.
That’s a very good program.
Same thing can also be done using semaphores.