为什么使用显示器时每个对象都有一个就绪和等待队列?如果一个线程完成了一个对象,只需弹出等待队列中的下一个项目。就绪队列似乎是多余的。
上下文是.NET,更具体地说是监视器类。
答案 0 :(得分:4)
生成器/消费者队列是了解Monitor类的一个非常好的用例。
假设偶尔将工作添加到队列中。有时候需要处理很多项目,有时候会有很长一段时间没有项目。
所以,假设你有k个消费者线程在等待处理队列中的项目。换句话说,每个线程实现一个紧密循环,不断尝试
lock
(这会让您进入Monitor的“就绪”队列)。如果你选择选项“a”,那么你的k个线程会浪费CPU周期一遍又一遍地通过就绪队列,找不到任何工作要做,并在队列后面重新开始。
如果你选择选项“b”,你会说“现在没有什么可以做的,让我睡觉,当有事情要做时叫醒我。”
使用选项“b”,如果队列为空,您很快就会发现所有消费者都在“等待”队列中休眠,并且没有浪费CPU时间。
然后,当生产者将一个项目添加到队列时,它会调用Monitor.Pulse。这会唤醒“等待”队列中的第一个线程,然后进入“就绪”队列的后面(如果“就绪”队列为空,它也是队列的前面)。
当一个线程获得锁并从队列中使用该项时,它再次调用Monitor.Enter,并转到“就绪”队列的后面。
有关.NET中生产者/消费者队列的经典实现,请参阅this article。
答案 1 :(得分:2)
假设我已正确理解你的问题,两者有不同的用途。
“就绪”队列用于可以在获得锁定后立即运行的线程。他们只是在等待获得锁定。这主要用于互斥,以防止两个线程同时使用相同的资源。
“等待”队列用于等待特定信号的线程 - 即监视器处于脉冲状态。这通常用于协调 - 例如在生产者/消费者队列中,如果队列为空,则消费者将等待监视器在再次检查队列之前发出脉冲。虽然没有人正在生产,没有人消费,但没有线程拥有监视器 - 没有资源在使用。但监视器用于协调消费者与生产者。