`

生产消费模型实例

阅读更多

“生产者-消费者-仓储”模型,包含三种角色:

1.生产者

2.消费者

3.仓库

 

离开了仓储,生产者消费者模型就显得没有说服力了。

 

对于此模型,应该明确一下几点:
1、生产者仅仅在仓储未满时候生产,仓满则停止生产。
2、消费者仅仅在仓储有产品时候才能消费,仓空则等待。
3、当消费者发现仓储没产品可消费时候会通知生产者生产。
4、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。

下面的三个类分别代表了生产者,消费者和仓库

package producerconsumer;

/**
 * <p>Description: Test</p>
 * <p>Copyright (c) 2010</p>
 * <p>Project:Test</p>
 *
 * @author Tomy Zhou
 * @since 1.0
 * @version producerconsumer; Producer.java
 *         2010-3-3
 **/
public class Producer extends Thread{
    Integer producedNumber;
    Ware ware;
   
    public Producer(Integer producedNumber, Ware ware){
        this.producedNumber = producedNumber;
        this.ware = ware;
    }
   
    public void run(){
        try{
            while(true){
                ware.put(producedNumber);
            }
        }catch (Exception e) {
            // TODO: handle exception
        }
       
    }

}

package producerconsumer;


/**
 * <p>Description: Test</p>
 * <p>Copyright (c) 2010</p>
* <p>Project:Test</p>
 *
 * @author Tomy Zhou
 * @since 1.0
 * @version producerconsumer; Consumer.java
 *         2010-3-3
 **/
public class Consumer extends Thread{
    Integer consumedNumber;
    Ware ware;
   
    public Consumer(Integer consumedNumber, Ware ware){
        this.consumedNumber = consumedNumber;
        this.ware = ware;
    }
   
    public void run(){
        try{
            while(true){
                ware.take(consumedNumber);
            }
        }catch (Exception e) {
            // TODO: handle exception
        }
       
    }
}

package producerconsumer;
/**
 * <p>Description: Test</p>
 * <p>Copyright (c) 2010</p>
  * <p>Project:Test</p>
 *
 * @author Tomy Zhou
 * @since 1.0
 * @version producerconsumer; Ware.java
 *         2010-3-3
 **/
public class Ware {
    int capacity;
    int size;
   
    public Ware(int capacity){
        this.capacity = capacity;
    }
   
    public void take(int number) throws InterruptedException{
        synchronized (this) {
            while(number>size){
                System.out.println(Thread.currentThread().getName()+"========The consumer number "+number+" is greater than the size=="+size+".Wait to put.");
                this.wait();
            }
           
            size = size -number;
            System.out.println(Thread.currentThread().getName()+"========Consumer the product========"+number+";The ware has the product======"+size);
            this.notifyAll();
        }
    }
   
    public void put(int number) throws InterruptedException{
        synchronized (this) {
            while(size+number>capacity){
                System.out.println(Thread.currentThread().getName()+"========The put number "+number+" plus the current ware size=="+size +" is greater than capacity=="+capacity+".Wait to consumer.");
                this.wait();
            }
           
            size = size +number;
            System.out.println(Thread.currentThread().getName()+"========Produced the product========"+number+";The ware has the product======"+size);
            this.notifyAll();
        }
    }
   
    public synchronized int size() {
        return size;
    }

下面代码大家想想:
  synchronized (this) {
            while(size+number>capacity){
                System.out.println(Thread.currentThread().getName()+"========The put number "+number+" plus the current ware size=="+size +" is greater than capacity=="+capacity+".Wait to consumer.");
                this.wait();
            }

为什么不能改成if (size+number>capacity)?

考虑下面的情况:
capacity:50
current size:40
生产线程Thread-0 put 20+ current size 40 = 60,线程阻塞,并释放锁
生产线程Thread-1 获取监控器的锁,并put10+currnet size 40=50,size=50,唤醒所有阻塞的线程
如果是if:Thread-0往下执行:size=50+20=70,显然超过了仓库的最大库存,在这种情况下就出现问题,如果改成while,Thread 0 仍然会阻塞,不会超过仓库的最大库存。




分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics