I'm trying to understand the inter-thread communication on Java and read that support comes with the use of the methods wait(), notify(), notifyAll().
For a thread to execute any of these methods, the thread must be the owner of the object lockfor which the thread calls (any of these) methods. In addition to this, all of these methods should be in a block / method synchronized. So far so good.
I tried to implement a program in which one thread prints odd numbers and another thread prints even numbers.
The program works correctly, however, at the same time, it raised a few more doubts.
Below is the full source code of the program that I implemented.
PrintEvenNumThread.java// prints even numbers
package com.example.multithr.implrun;
import com.example.common.ObjectToWaitOn;
public class PrintEvenNumThread implements Runnable {
private ObjectToWaitOn objectToWaitOn;
public PrintEvenNumThread(ObjectToWaitOn objectToWaitOn) {
this.objectToWaitOn = objectToWaitOn;
}
@Override
public void run() {
int numToPrint = 2;
for (;;) {
synchronized (objectToWaitOn) {
while(objectToWaitOn.getPrintEvenOrOdd() != 2) {
try {
objectToWaitOn.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
objectToWaitOn.print("EvenThread",numToPrint);
numToPrint += 2;
objectToWaitOn.setPrintEvenOrOdd(1);
objectToWaitOn.notifyAll();
}
}
}
}
PrintOddNumsThread.java//
package com.example.multithr.implrun;
import com.example.common.ObjectToWaitOn;
public class PrintOddNumsThread implements Runnable {
private ObjectToWaitOn objectToWaitOn;
public PrintOddNumsThread(ObjectToWaitOn objectToWaitOn) {
this.objectToWaitOn = objectToWaitOn;
}
@Override
public void run() {
int numToPrint = 1;
for(;;) {
synchronized(objectToWaitOn) {
while(objectToWaitOn.getPrintEvenOrOdd() != 1) {
try {
objectToWaitOn.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
objectToWaitOn.print("OddThread", numToPrint);
numToPrint += 2;
objectToWaitOn.setPrintEvenOrOdd(2);
objectToWaitOn.notifyAll();
}
}
}
}
ObjectToWaitOn.java// ""
package com.vipin.common;
public class ObjectToWaitOn {
private int printEvenOrOdd;
public ObjectToWaitOn(int printEvenOrOdd) {
this.printEvenOrOdd = printEvenOrOdd;
}
public int getPrintEvenOrOdd() {
return printEvenOrOdd;
}
public void setPrintEvenOrOdd(int printEvenOrOdd) {
this.printEvenOrOdd = printEvenOrOdd;
}
public void print(String byThread, int numToPrint) {
System.out.println(byThread + ": " +numToPrint);
}
}
PrintEvenOddNumsMainApp.java
package com.example.multithr.main.app1;
import com.example.common.ObjectToWaitOn;
import com.example.multithr.implrun.PrintEvenNumThread;
import com.example.multithr.implrun.PrintOddNumsThread;
public class PrintEvenOddNumsMainApp {
public static void main(String[] args) {
ObjectToWaitOn obj = new ObjectToWaitOn(1);
PrintEvenNumThread printEvenNumThread = new PrintEvenNumThread(obj);
PrintOddNumsThread printOddNumsThread = new PrintOddNumsThread(obj);
Thread evenNum = new Thread(printEvenNumThread);
Thread oddNum = new Thread(printOddNumsThread);
evenNum.start();
oddNum.start();
}
}
:
1) - , notifyAll() objectToWaitOn ( ), ? , synchronized objectToWaitOn; notifyAll(), , , ?
2) , wait() objectToWaitOn, , notifyAll(), - ? , synchronized, , ; , objectToWaitOn synchronized, objectToWaitOn, ?
- ?