I am trying to get my Producer/Consumer working and I deliberately don't want to use BlockingQueue to understand finer details here. I understand when I call object.wait() the thread looses its lock and goes to WAITING state till someone notifies (notify/notifyAll) which beings it back to BLOCKED state and this thread would go to RUNNABLE if it acquires the lock.
private class Consumer implements Runnable{
private final MyQueue<Integer> queue;
public Consumer(MyQueue<Integer> queue){
this.queue = queue;
}
@Override
public void run(){
while(true){
synchronized (queue) {
//Block till new available
while(queue.isEmpty()){
try {
queue.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//Consume
queue.dequeue();
queue.notifyAll(); //Notify people waiting on queue full condition
}
}
}
}
My question is it possible that (with respect to code above):
- My thread was waiting and woke up after wait (some one notified) and i got the lock
- I made a check queue.isEmpty() and it was not empty and execution goes to next line
- Just before the next line queue.dequeue() is executed CPU context switched my thread.
- Next when i get my cpu slice and lock, i run queue.dequeue() and say queue is empty
I know a usual CPU scheduler gives a quantum of time to each thread to avoid the context switching costs.