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();
}
}