生产者生产和消费者消费不一定会一一对应,为了解决这个问题引入缓存概念(容器)。生产者生产的产品,放在容器中,消费者要消费时从容器中提取。要注意的情况:
1.生产者生产时候,消费者不能消费;
2.消费者消费时候,生产者不能生产产品;
3.容器为空(empty)时候,提醒(notify)生产者生产产品;
4.容器满的时候,提醒消费者消费;
引入生产者消费者模式的好处:
1.解耦合。让生产者和消费者不用直接联系上,解耦合。
2通过平衡生产者消费者之间的关系,使他们打到动态平衡。
生产者/消费者模型最终达到的目的是平衡生产者和消费者的处理能力,达到这个目的的过程中,并不要求只有一个生产者和一个消费者。可以多个生产者对应多个消费者,可以一个生产者对应一个消费者,可以多个生产者对应一个消费者。
假死就发生在上面三种场景下。理论分析就能说明问题,所以就不写代码了。代码要写也很简单,上面的两个例子随便修改一个,开一个生产者线程/多个消费者线程、开多个生产者线程/消费者线程、开多个生产者线程/多个消费者线程都可以。假死指的是全部线程都进入了WAITING状态,那么程序就不再执行任何业务功能了,整个项目呈现停滞状态。
比方说有生产者A和生产者B,缓冲区由于空了,消费者处于WAITING。生产者B处于WAITING,生产者A被消费者通知生产,生产者A生产出来的产品本应该通知消费者,结果通知了生产者B,生产者B被唤醒,发现缓冲区满了,于是继续WAITING。至此,两个生产者线程处于WAITING,消费者处于WAITING,系统假死。
上面的分析可以看出,假死出现的原因是因为notify的是同类,所以非单生产者/单消费者的场景,可以采取两种方法解决这个问题:
1、synchronized用notifyAll()唤醒所有线程、ReentrantLock用signalAll()唤醒所有线程
2、用ReentrantLock定义两个Condition,一个表示生产者的Condition,一个表示消费者的Condition,唤醒的时候调用响应的Condition的signal()方法就可以了
网友评论