Java设计模式 - 生产者、消费者

     对于多线程程序来讲,无论任何编程语言,生产者和消费者模型都是最经典的。就像学习每一门编程语言同样,Hello World!都是最经典的例子。java

     实际上,准确说应该是“生产者-消费者-仓储”模型,离开了仓储,生产者消费者模型就显得没有说服力了。编程

     对于此模型,应该明确一下几点:多线程

一、生产者仅仅在仓储未满时候生产,仓满则中止生产。编程语言

二、消费者仅仅在仓储有产品时候才能消费,仓空则等待。ide

三、当消费者发现仓储没产品可消费时候会通知生产者生产。学习

四、生产者在生产出可消费产品时候,应该通知等待的消费者去消费。this

 

     此模型将要结合java.lang.Object的wait与notify、notifyAll方法来实现以上的需求。这是很是重要的。 线程

     注意:1.用while判断而不用if,由于while能保证在等待中的线程被唤醒后可以先进行while判断,若是是if则再也不判断,会致使错误。code

               2.用notifyAll而不用notify,由于notify仅通知相同类型的线程,这时,若是该类型线程处于等待则整个程序会产生死锁;若是使用notifyAll则通知了全部线程,这样总能有线程继续运行下去,程序不会产生死锁。blog

/**
 *
 * @author Yuanyuan
 */
public class TestCP
{
    public static void main(String[] args)
    {
        Base b = new Base(20);
        Customer1 c1 = new Customer1(b, 10);
        Customer1 c2 = new Customer1(b,20);   
        Customer1 c3 = new Customer1(b,20);   
        Producer1 p1 = new Producer1(b, 10);
        c1.start();
        c2.start();
        c3.start();
        p1.start();
    }
}
  
    
   class Base
   {
       private static final int total = 100;
       private int current;
       public Base(int initSize)
       {
           this.current = initSize;
       }
       public Base()
       {
       }
       public synchronized void produce(int size)
       {
           while (size > total - current)
           {
               System.out.println("要生产的产品量" + size + "超出了仓库剩余容量" + (total - current) + ",暂时没法生产!");
               try
               {
                   this.wait();
               } catch (Exception ex)
               {
                   System.out.println(ex.getMessage());
                   ex.printStackTrace();
               }
           }
           current = current + size;
           System.out.println("新生产了" + size + ",当前库存" + current);
           this.notifyAll();
       }
       public synchronized void custum(int size)
       {
           while (size > current)
           {
               System.out.println("要消费的产品量" + size + "超出了库存" + current + ",暂时没法消费!");
               try
               {
                   this.wait();
               } catch (Exception ex)
               {
                   System.out.println(ex.getMessage());
                   ex.printStackTrace();
               }
           }
           current = current -size;
           System.out.println("新消费了"+size+"当前库存"+current);
           this.notifyAll();
       }
       
   }
   
   class Producer1 extends Thread
   {
       private Base b;
       private int size;
       public Producer1(Base b,int size)
       {
           this.b = b;
           this.size = size;
       }
       @Override
        public void run()
        {
            b.produce(size);
        }
    }
    
    class Customer1 extends Thread
    {
        private Base b;
        private int size;
        public Customer1(Base b, int size)
        {
            this.b = b;
            this.size = size;
        }
        @Override
        public void run()
        {
            b.custum(size);
        }
    }

运行结果:

新消费了10当前库存10

新生产了10,当前库存20

新消费了20当前库存0

要消费的产品量20超出了库存0,暂时没法消费!

参考资料:http://lavasoft.blog.51cto.com/62575/221932/

相关文章
相关标签/搜索