问题分析
1.生产者消费资源放入仓库,消费者从仓库获取资源,所以,仓库作为生产者和消费者的公共资源,本质上来说就是考察线程之间对公共资源的操作引起的线程安全和线程通信问题。
2.代码实现:
库存类
public class Depot {
private int capacity ; //库存总容量(固定不变)
private int currentCapacity; //库存当前容量
public Depot(int capacity,int currentCapacity) {
this.capacity = capacity;
this.currentCapacity = currentCapacity;
}
/**
* 定义具体的生产方法
* @param num:每次生产数量
*/
public synchronized void realProduce(int num) { //synchronized修饰普通方法时,锁的是类的一个实例,如果实例不同,则锁失效
//首先判断当前库存(只要库存没满,就一直生产)
if(currentCapacity<capacity) { //当前库存小于库存总量,则需要生产
//生产
this.currentCapacity+=num;
System.out.println(Thread.currentThread().getName()+" 生产出"+num+"件产品,当前库存:"+this.currentCapacity);
notifyAll(); //唤醒正在等待的消费者线程(调用wait,notify等方法时,需要线程持有该对象的锁,当前对象是Depot)
}else {
try {
System.out.println("库存已满,不需要生产,生产者进入等待状态");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
/**
* 定义具体消费方法
* @param num:每次消费数量
*/
public synchronized void realConsume(int num) {
if(currentCapacity<num) { //表示没有东西可消费
try {
//进入等待状态
System.out.println("库存不足,消费者进入等待状态!");
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
//消费
this.currentCapacity-=num;
System.out.println(Thread.currentThread().getName()+" 消费"+num+"件产品,唤醒正在等待的生产者来生产,当前库存:"+this.currentCapacity);
notify();
}
}
}
生产者类
public class Producer extends Thread{
//分析:1.生产者生不生产,取决于库存,所以,生产者必须得持有库存对象;
// 2.生产者生产的物品需要放入库存,消费者才能从库存获取,然后再消费,所以,库存作为连接生产者和消费者的中间桥梁,需同时持有生产和消费方法,
// 3.因此,可以将具体的生产方法定义在库存,生产者这边持有调用即可;同理,具体的消费方法定义在库存,消费者端再持有调用即可。
private Depot depot;
public Producer(Depot depot,String name) {
super(name);
this.depot = depot;
}
@Override
public void run() {
while(true) { //一直生产
try {
Thread.sleep(1000);
depot.realProduce(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
消费者类
public class Consumer extends Thread{
private Depot depot;
public Consumer(Depot depot,String name) {
super(name);
this.depot = depot;
}
@Override
public void run() {
while(true) { //一直消费
try {
Thread.sleep(1000);
depot.realConsume(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试
public class Test {
public static void main(String[] args) {
Depot depot = new Depot(10,0); //库存总量是10,当前库存是0
Producer producer = new Producer(depot,"producer");
Consumer consumer = new Consumer(depot,"consumer");
producer.start(); //每次生产1件
consumer.start(); //每次消费2件
}
}