1
我想让我的生产者/消费者工作,我故意不想使用BlockingQueue在这里了解更细的细节。我明白,当我调用object.wait()时,线程松开它的锁并进入WAITING状态,直到有人通知(notify/notifyAll)使其返回到BLOCKED状态,并且如果线程获取锁,则该线程将转到RUNNABLE。可以等待的线程,再次唤醒上下文切换
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
}
}
}
}
我的问题是有可能,(上面相对于代码):
- 我的线程在等待和观望后醒来(有些人通知) 和我得到了锁
- 我做了一个检查queue.isEmpty(),它不是空的,执行到下一行
- 就在下一行queue.dequeue()被执行之前,CPU上下文切换了我的线程。
- 下一页当我得到我的CPU片和锁,我运行queue.dequeue(),并说队列为空
我知道通常CPU调度程序提供了时间量子给每个线程,以避免上下文切换成本。
上下文切换的线程是否保存锁定并退出执行? – Monish 2014-10-19 13:45:58
线程保持锁定状态直到它离开同步块。线程当前是否正在执行并不会改变任何内容。如果调度程序决定在while循环之后和调用dequeue之前立即切换到其他线程,则等待该锁的所有其他线程将继续被阻塞,直到持有锁的线程重新计划为止,并继续执行直到它离开同步块。 – 2014-10-19 13:50:18
谢谢!这使得它非常清晰:“线程保持锁定状态,直到它离开同步块为止,线程当前是否正在执行不会改变任何内容”。虽然有趣的是,当OS上下文切换时,它可能会减慢正在等待锁定的线程 – Monish 2014-10-19 13:59:44