什么是生产消费者模型?
来看一张图
简单来说生产消费者模型就是生产者与消费者共同操作共有资源的一种形式。举个例子,例如,几个商人到茶园批发茶叶,这就是消费者,茶园工作人员就是生产者,工作人员生产茶叶,商人消费茶叶,他们具有共同的资源平台,就是茶叶仓库。这个时候,在对共有资源实现操作的时候,信息就显得尤为重要,工作人员作为生产者,生产了茶叶以后通知商人来消费,商人作为消费者,如果发现货物数量不足或者没货,就会联系生产者生产茶叶,这是一个相互传递信息,共同处理共有资源的一种形式。
体现在程序中,我们可以模拟生产者与消费者,通过线程的唤醒与等待实现共同对仓库的资源处理。这里要注意消费者与生产者一次只能有一个人进入仓库取货和放货,这主要是为了防止线程安全问题。
这里为了实现此模型需要用到线程中的两个状态。
wait() 会执行该方法的当前的线程进入等待状态 ;
notifyAll() 唤醒所有被wait()的线程;
消费者
先拿到仓库的锁,进入仓库,查看仓库中是否有货,有,可进行购买,然后释放仓库锁;如果没有货,唤醒生产者生产货物,释放仓库锁。
生产者
进入仓库查看仓库库存是否已满;已满,唤醒消费者消费,自己进入等待状态,释放仓库锁,未满,生产产品并唤醒消费者,然后释放锁。
仓库
具有仓库容量的属性,因为是共有资源,还需要加锁,避免出现线程安全问题。
下面上代码
消费者:
package com.wt0812;
public class Consumer extends Thread{
private Storehouse storage;
public Consumer(){}
public Consumer(Storehouse storage){
this.storage = storage;
}
@Override
public void run(){
while(true){
try{
Thread.sleep(3000);
storage.consume();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
生产者
package com.wt0812;
public class Producer extends Thread{
private Storehouse Storehouse;
public Producer(){}
public Producer(Storehouse Storehouse){
this.Storehouse = Storehouse;
}
@Override
public void run(){
while(true){
try{
Thread.sleep(1000);
Storehouse.produce();
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
}
仓库及主程序
package com.wt0812;
import java.util.LinkedList;
public class Storehouse {
private int MAX_SIZE = 10;
private LinkedList<Object> list = new LinkedList<>();
public static void main(String[] args) {
Storehouse storage = new Storehouse();
Producer p1 = new Producer(storage);
Producer p2 = new Producer(storage);
Producer p3 = new Producer(storage);
Consumer c1 = new Consumer(storage);
Consumer c2 = new Consumer(storage);
Consumer c3 = new Consumer(storage);
p1.start();
p2.start();
p3.start();
c1.start();
c2.start();
c3.start();
}
public void produce() {
synchronized (list) {
while (list.size() + 1 > MAX_SIZE) {
System.out.println("生产者" + Thread.currentThread().getName()+ "仓库已满");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(new Object());
System.out.println("生产者" + Thread.currentThread().getName()+ "生产一个产品,现库存" + list.size());
list.notifyAll();
}
}
public void consume() {
synchronized (list) {
while (list.size() == 0) {
System.out.println("消费者" + Thread.currentThread().getName() + "仓库为空");
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove();
System.out.println("消费者" + Thread.currentThread().getName()+ "消费一个产品,现库存" + list.size());
list.notifyAll();
}
}
}