生产者消费者问题的java实现

问题分析

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件
     
    }


}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值