1.生产者消费者模式
设计要点是 tray
-
生产者,消费者都要将对应的托盘对应为实例域
-
托盘的核心是一个DataQueue,但是tray并不直接将DataQueue的add和remove方法暴露给生产者消费者,而是 通过get()和put()方法。
-
get()和put()方法内部通过synchronized保护;内部通过while- wait - notify机制实现高效的轮流占有tray。注意是while而不是if, 因为可能有众多的生产者消费者,某个消费者得到了锁并不一定意味此时DataQueue不为空(可能是被其他消费者notify后得到锁,也可能是在得到锁前put的Data已经先被其他消费者获取了),因此还要再次判断DataQueue是否为空。
-
while - wait - notify
如果生产者和消费者都使用 while - wait - notify模式,那么必须0 <= 生产者produce的data数 - 消费者consmue的data数 <= 托盘总容量
否则总会一方处于wait状态(没有被notify)而导致程序无法结束。
-
对while - wait - notify的改进
OO第二单元作业电梯调度,可以将Input进程视为Producer,但是由于不能预先知道Producer产生的请求指令数(因此生产者消费者内部不再采用for循环计数,而是采用while循环),因此如果直接使用while-wait-notify可能会导致程序无法结束。改进:
方法1. 采用 if (空) - sleep - else - DataQueue.remove , 但是我再另一篇文章中有说,需要设置标志位将sleep移出监控区,否则会导致效率极低。方法2. 采用if(空) - wait - else - DataQueue.remove(相比之前while之后一定会执行remove操作,在这里为空就不执行remove了)。但是需要控制好结束消费者循环的条件 。