目的:编制生产者—消费者算法,模拟一个生产者、一个消费者,共享一个缓冲池的情形。
1、实现对经典的生产者—消费者问题的模拟,以便更好的理解此经典进程同步问题。
生产者-消费者问题是典型的PV操作问题,假设系统中有一个比较大的缓冲池:
生产者的任务是只要缓冲池未满就可以将生产出的产品放入其中。消费者的任务是只要缓冲池未空就可以从缓冲池中拿走产品。缓冲池被占用时,任何进程都不能访问。
2、每一个生产者都要把自己生产的产品放入缓冲池,每个消费者从缓冲池中取走产品消费。
在这种情况下,生产者消费者进程同步,因为只有通过互通消息才知道是否能存入产品或者取走产品。他们之间也存在互斥,即生产者消费者必须互斥访问缓冲池,即不能有两个以上的进程同时进行。
Java代码实现:
-
缓冲池类:
public class BufferArea {
private int in=0;//存放
private int out=0;//取出
private int Max=10;//容量
private int num=0;//数量
public int getIn() {
return in;
}
public void setIn(int in) {
this.in = in;
}
public int getOut() {
return out;
}
public void setOut(int out) {
this.out = out;
}
public int getMax() {
return Max;
}
public void setMax(int max) {
Max = max;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Production[]pba=new Production[10];
public synchronized void set(Production p) {
if(num<Max) {
System.out.println("第"+in+"存放了产品"+p);
pba[in]=p;
in=(in+1)%Max;
num++;
notifyAll();
}else {
try {
wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}
public synchronized Production get() {
Production p=null;
if(num>0) {
num--;
p=pba[out];
System.out.println("第"+out+"位产品取出"+p);
out=(out+1)%Max;
notifyAll();
}else {
try {
wait();
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
return p;
}
}
-
生产者类:
public class Producer implements Runnable {
private BufferArea ba;
private Production p;
public Producer(BufferArea ba) {
this.ba=ba;
}
public void setP() {
//编号 类别 颜色 重量 形状
p=new Production(Math.round(Math.random()*10000000),"凳子","红色",300,"方形");
}
@Override
public void run() {
// TODO 自动生成的方法存根
while(true) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
this.setP();
ba.set(this.p);
}
}
}
-
产品类:
public class Production {
//编号 类别 颜色 重量 形状
private long code=0;
private String type="";
private String color="";
private double weight=0;
private String shape="";
public long getCode() {
return code;
}
public void setCode(long code) {
this.code = code;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public double getWeight() {
return weight;
}
public void setWeight(double weight) {
this.weight = weight;
}
public String getShape() {
return shape;
}
public void setShape(String shape) {
this.shape = shape;
}
public Production() {
super();
// TODO 自动生成的构造函数存根
}
public Production(long code, String type, String color, double weight, String shape) {
super();
this.code = code;
this.type = type;
this.color = color;
this.weight = weight;
this.shape = shape;
}
@Override
public String toString() {
return "Production [code=" + code + ", type=" + type + ", color=" + color + ", weight=" + weight + ", shape="
+ shape + "]";
}
}
-
测试类:
public class Test {
public static void main(String[] args) {
BufferArea ba=new BufferArea();
Producer pro1=new Producer(ba);
Consumer con1=new Consumer(ba);
Thread tp1=new Thread(pro1,"生产者1");
Thread tp2=new Thread(pro1,"生产者2");
Thread tp3=new Thread(pro1,"生产者3");
Thread tc1=new Thread(con1,"消费者1");
Thread tc2=new Thread(con1,"消费者2");
Thread tc3=new Thread(con1,"消费者3");
tp1.start();
tc1.start();
tp2.start();
tc2.start();
tp3.start();
tc3.start();
}
}