需求分析:
- 产品、生产者、消费者,生产者每次生产将产品数+1,消费者每次消费将产品数-1;
- 消费者消费的时候,产品数要大于0才能被消费;
- 当商品数大于20的时候,停止生产;
- 当商品数小于5的时候,停止消费。
模拟流程:
假如消费者先抢到线程,初始产品数为0,则不会消费。
假如生产者先抢到线程,生产出了第1个商品;
下次消费者抢到线程,判定数量为1大于0,但是其小于5,消费者暂停消费(休眠);
当生产者生产了1,2,3,4个商品的时候,消费者都是小于5,会继续暂停(休眠);
当生产者生产了5个或者更多商品的时候,消费者判定大于5,会进行消费(-1);
当生产者生产了21个商品的时候,判定大于20个最大容量,生产者会暂停生产(休眠);
消费者消费了1个,同时唤醒生产者,生产者继续判定,如果大于20会继续休眠,小于20则开始生产;
生产者生产了1个,同时唤醒消费者,消费者继续判定,如果小于5会继续休眠,大于5则开始消费。
代码实现过程
重点在于产品类中的生产和消费方法
//重点在产品类上
class Product{
private int count = 0;
//每次生产+1
public synchronized void product() {
//如果产品多于20个的时候,停止生产
if(count >20){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产第"+ ++count +"个产品");
//生产后,唤醒消费者
notify();
}
//每次消费-1
public synchronized void consume() {
//产品大于0才能够被消费
if(count > 0){
//如果产品小于5个的时候,停止消费
if(count < 5){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费第"+ count-- +"个产品");
//消费后,唤醒生产者
notify();
}
}
}
生产者和消费者
//生产者
class Producter implements Runnable{
private Product product;
public Producter(Product product) {
this.product = product;
}
@Override
public void run() {
while (true){
product.product();
}
}
}
//消费者
class Comsumer implements Runnable{
public Comsumer(Product product) {
this.product = product;
}
private Product product;
@Override
public void run() {
while (true){
product.consume();
}
}
}
测试
public class A {
public static void main(String[] args) throws InterruptedException {
Product product = new Product();
//启动生产者线程
new Thread(new Producter(product)).start();
//启动消费者线程
new Thread(new Comsumer(product)).start();
}
}
结果:
生产第20个产品
生产第21个产品 //库存大于20的时候,不会继续生产
消费第21个产品
消费第20个产品
消费第19个产品
消费第18个产品
消费第17个产品
消费第16个产品
消费第15个产品
消费第14个产品
消费第13个产品
消费第12个产品
消费第11个产品
消费第10个产品
消费第9个产品
消费第8个产品
消费第7个产品
消费第6个产品
消费第5个产品 //库存小于5的时候,不会继续消费
生产第5个产品
生产第6个产品