Please note that this is not the actual scenario. I created a sample scenario based on my actual implementation, to make it easy to review. I am also already getting the expected output too. However, I need to clarify some concepts regarding the wait()
and notifyAll()
methods in Java. (In here both these threads will starts there run method at once in the main thread.) So according to my knowledge, since thread B is sleeping, because you can see at the initial stage reamingCount is 400.
So thread B will calls its MUTEX.wait()
and continue its sleep until some other thread invokes a notify()
or notifyAll()
, then after the remainingCount decrements to 0, thread A will call MUTEX.notifyAll();
to awake the thread B and MUTEX.wait()
to release its already granted lock, and go to sleep until thread B notifies it.
When I call MUTEX.notifyAll()
through thread A, won't thread B wake up and continue its task before thread A calls MUTEX.wait()
?
I mean, you can see when thread A calls the MUTEX.notifyAll()
, thread B will awake and check again if the condition in the while loop is true or false. So, since the remainingCount is equal to 0, thread B will exit the while loop and continue its task before thread A calls wait()
. Won't this scenario break the principle of wait()
? According to my knowledge thread B can only continue its execution when thread A calls wait()
.
public class A implements Runnable{
public static volatile remainingCount =400;
private final Object MUTEX;//Both class A and B holds the same object mutex
private void methodA(){
synchronized(MUTEX){
while(remainingCount == 0){
MUTEX.notifyAll();
MUTEX.wait();
}
//Perform it's usual task.In here remaining count will decrement during the process.
}
@Override
public void run() {
while(true){
methodA();
}
}
}
}
public class B implements Runnable{
private final Object MUTEX;//Both class A and B holds the same object mutex
private void methodB(){
synchronized(MUTEX){
while (A.remainingCount != 0) {
try {
MUTEX.wait();
} catch (InterruptedException ex) {
Logger.getLogger(InkServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
}
}
//incrementing the A.remainingCount
MUTEX.notifyAll();
}
@Override
public void run() {
while(true){
methodB();
}
}
}
question from:
https://stackoverflow.com/questions/65651597/behavior-of-wait-and-notifyall-in-java 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…