/**
*    
*/

package mythread;

/**
* @author daniel zhou    
* 演示生产者、消费者模型
*/

public class WaitAndNotify {

   /**
    * @param args
    */

   public static void main(String[] args) {    
     // 定义一个储物罐
    Queue q = new Queue();
     // 生产者
    producer p = new producer(q);
     // 消费者
    consumer c = new consumer(q);
     // 开始生产、消费过程
    p.start();
    c.start();
    System.gc();
  }

}

/**
*    
* @author daniel zhou 储物罐,用作存储生产者的产品
*/

class Queue {
   // 产品编号
   int value;
   // 有无产品标示
   boolean flag = false;

   // 生产
   public synchronized void put( int i) {
     // 为空则放置,并通知消费者去取产品,自己则开始等待
     if (!flag ) {
      value = i;
      flag = true;
       // 通知消费者
      notify();
    }

     // 开始等待
     try {
      wait();
    } catch (InterruptedException e) {
       // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

    
   // 消费
   public synchronized int get() {
     // 有产品则取,并标示已经置空,通知生产者放置,自己开始等待
     if (!flag ) {

       // 开始等待
       try {
        wait();
      } catch (InterruptedException e) {
         // TODO Auto-generated catch block
        e.printStackTrace();
      }
    }

     // 通知生产者并返回产品
    flag = false;
    notify();
     return value;
  }

    
}

/**
*    
* @author daniel zhou 消费者
*/

class consumer extends Thread {
  Queue q;

   public consumer(Queue q) {
     this.q = q;
  }

   // 消费10个产品
   public void run() {    
     //这个while必须要
     while( true){
      System.out.println( "消费者消费了第" + q.get() + "个产品");
    }
  }
}

/**
*    
* @author daniel zhou 生产者
*/

class producer extends Thread {
  Queue q;
    
   public producer(Queue q) {
     this.q = q;
  }

   // 生产10个产品
   public void run() {
     for ( int i = 0; i < 10; i++) {
      q.put(i);
      System.out.println( "生产者放置了第" + i + "个产品");
    }
  }
}