package com.thread.sync; //著名的生产者消费者程序 //生产者向容器里放东西,同时消费者取出去 public class ProducerConsumer { public static void main(String[] args) { Container container = new Container(); Producer producer = new Producer(container); Consumer consumer = new Consumer(container); new Thread(producer).start(); new Thread(consumer).start(); new Thread(producer).start(); } } //产品类 class Produce { int id; public Produce(int id) { super(); this.id = id; } @Override public String toString() { return "produce"+id; } } //容器类,先进去后拿出来 class Container { //表示装到第几个了 int index = 0; //假定容量为6 Produce[] p = new Produce[1000]; //往容器里装的方法 public synchronized void push(Produce p) { //当容器装满的时候 //this.wait表示,锁定在当前对象的线程等待 //用while,使用if不合适,如果出异常,会出错 while(index == this.p.length) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); this.p[index] = p; index ++; } //从容器取方法 public synchronized Produce pop() { while(index==0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } // 唤醒在此对象监视器上等待的单个线程。 this.notifyAll(); index --; return p[index]; } } //生产者 class Producer implements Runnable { //生产者得知道他往那个容器里装,所以他得有容器的一个引用 Container c = null; //创建生产者的时候告诉他往那个容器里生产,所以这个构造方法是必要的 public Producer(Container c) { super(); this.c = c; } //生产产品的方法 public void produce() { for(int i=0;i<100;i++) { Produce p = new Produce(i); c.push(p); System.out.println("生产了:" + p); try { Thread.sleep((int)(Math.random())*50); } catch (InterruptedException e) { e.printStackTrace(); } } } @Override public void run() { produce(); } } //消费者 class Consumer implements Runnable { //生产者得知道他往那个容器里装,所以他得有容器的一个引用 Container c = null; //创建生产者的时候告诉他往那个容器里生产,所以这个构造方法是必要的 public Consumer(Container c) { super(); this.c = c; } //消费产品的方法 public void consume() { for(int i=0;i<100;i++) { Produce p = c.pop(); System.out.println("消费了:" + p); try { Thread.sleep((int)(Math.random())*50); } catch (InterruptedException e) { e.printStackTrace(); } } } @Override public void run() { consume(); } }