注:为了便于理解,我使用了不规范的写法汉字来命名。
生产者生产产品,消费者消费产品,商店作为中间商从生产者那里进货,然后再把这些货买个消费者。
产品代码:
package xiancheng.生产者消费者;
public class 产品 {
private Integer id;
public 产品(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "产品{" +
"id=" + id +
'}';
}
}
商店代码:
package xiancheng.生产者消费者;
//负责从生产者那里进货,将商品卖给消费者
public class 商店 {
//描述了库存最多存放10个产品
private 产品[] 库存 = new 产品[10];
private int index = 0;
private int 实际库存量 = 0;
//这个会被生产者调用,将产品传递过来
public synchronized void 进货(产品 cp) {
if (实际库存量 == 10) {
//库存满了,不能放了
System.out.println("库存满了,请不要再进货了");
try {
wait();//让当前线程等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//将产品放入到库存中
库存[index] = cp;
index++;
实际库存量++;
notify();//生产者发货了, 商店就有产品了 唤醒消费者的线程
}
public synchronized 产品 卖出() {
if (实际库存量==0){
System.out.println("没货了,请稍等!");
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//获取到库存中的最后一个产品
产品 cp = 库存[index-1];
//删除这个产品
index--;
实际库存量--;
notify();//当消费者购买产品后 库存减少了 就可以继续进货了 唤醒生产者线程
return cp;
}
}
生产者代码:
package xiancheng.生产者消费者;
//负责生产产品
public class 生产者 extends Thread {
private 商店 sd;
public 生产者(商店 sd) {
this.sd = sd;
}
@Override
public void run() {
//负责生产产品
for (int i = 0; i < 20; i++) {
产品 cp = new 产品(i + 1);//生产产品
sd.进货(cp);
System.out.println("生产了产品:" + cp);
try {
Thread.sleep(1000);//每隔1秒生产一次产品
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
消费者代码:
package xiancheng.生产者消费者;
//负责消费产品
public class 消费者 extends Thread{
private 商店 sd;
public 消费者(商店 sd) {
this.sd = sd;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
产品 cp=sd.卖出();
System.out.println("购买了产品"+cp);
try {
Thread.sleep(3000);//每隔3秒消费一次产品
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
主方法:
package xiancheng.生产者消费者;
public class App {
public static void main(String[] args) {
商店 sd = new 商店();
生产者 scz = new 生产者(sd);
消费者 xfz=new 消费者(sd);
scz.start();
xfz.start();
}
}