生产者消费者模型是Java中线程通讯的一个经典模型,以下给出一种常见的写法,关于该模型的分析这里不再详细分析。
public class Model {
public static void main(String[] args){
//构建容器对象
//参数cap:代表容器数据的数量
Container c=new Container(5);
//构建生产者对象
//为何要有参数c?——因为c是Container类型的,
//而生产数据的方法put(data)是定义在Container类里面的。
Producer pro=new Producer(c);
//构建消费者对象
//为何要有参数c?——同上。
Consumer con=new Consumer(c);
//启动生产者线程
pro.start();
//启动消费者线程
con.start();
}
//容器,存储数据
class Container {
//用一个数组来代表容器,Object表示这个容器可以存放任意类型的数据
private Object[] object;
//用一个变量来记录数组中有效元素的个数
private int size;
//构造方法
public Container(int cap){this.object=new Object[cap];}
//向容器存放数据——生产者
//参数data:要向容器放数据
public synchronized void put(Object data){
//1.先判断容器是否已满
//size是生产者要存放数据的数量
//如果容器满了,则不能生产数据,需要等待消费者来取数据
if(object.length==size){
this.wait();
}
//如果容器不满,则生产者就放数据进去
//数据放到容器里面,就是向数组存储数据。
object[size]=data;
//存完后,通知消费者来取数据
//通知消费者取数据
this.notify();
}
//从容器取数据——消费者
public synchronized void take(){
//1.先判断容器有没有数据可以取
//如果容器中数据的数量为0,则等待生产者生产数据
if(size==0){
this.wait();
}
//否则的话,先将容器数据的数量减1
size--;
//接着就可以取数据
Object data=object[size];
//可以放到这里吗?
//size--;
//打印下取出的数据
System.out.println("output:"+data);
//切记切记:初始化当前数据的位置为null!!!
object[size]=null;
//取出来,通知生产者生产数据
this.notify();
}
}
//消费者线程
class Consumer extends Thread{
//定义一个容器对象,用来调用取出的方法
private Container c;
//在构造方法中创建容器对象,即为对象c开辟内存空间。
public Consumer(Container c){this.c=c;}
@Override
public void run(){
while(true){c.take();}
}
}
//生产者线程
class Producer extends Thread{
//定义一个容器对象,用来调用生产数据的方法
private Container c;
//在构造方法中创建容器对象,即为对象c开辟内存空间。
public Producer(Container c){this.c=c;}
//启动一个工作线程
@Override
public void run(){
//提示用户输入要存放的数据的大小
Scanner sc=new Scanner(System.in);
while(true){
System.out.println("input:");
Object data=sc.nextLine();
c.put(data);}
}
}
}