I know calling the wait()
method without getting ownership on object would lead to Exception.
and From Java doc,on calling the wait()
The thread
* releases ownership of this monitor and waits until another thread
* notifies threads waiting on this object's monitor to wake up
* either through a call to he {@code notify}
method or the
* {@code notifyAll}
method.
so once wait()
is called on object,that particular thread looses ownership on that on that object,until some other thread notifies it.
Why does calling wait()
twice without notifying,not throwing an error?
To make sure,..I just ran producer,so no other thread's i there to notify it and wait()
method is called infinite times.
Yet despite loosing ownership of that after first wait()
call,the subsequent wait calls should throw exceptions.isn't?but why is it working fine?
class Producer extends Thread {
private Queue<Integer> queue;
private int maxSize;
public Producer(Queue<Integer> queue, int maxSize, String name) {
super(name);
this.queue = queue;
this.maxSize = maxSize;
}
public void run() {
while (true) {
synchronized (queue) {
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
If you only run that thread, it will block after (in) the wait (try adding a debug output).
wait()
blocks until notified, and reacquires the lock before returning. I.e., when wait()
returns in your example, you again have locked queue
.
Edit: per update of question
Thus, "calling wait()
twice without notifying" is not possible, as the first call to wait()
will block the thread until notified. It cannot be called infinite times in the loop, it either blocks or throws an exception.
Addition:
By the way, having a "naked" wait is often risky, as there is no guarantee which of the waiting threads is woken up (e.g., a producer or a consumer).
A common idiom (as Java "built-in monitors" -- synchronized
blocks -- do not have condition variables) is something like
while(! condition)
wait();
In this case, for a consumer, perhaps something like
while(queue.isEmpty())
wait();