package com.sxtscience.msb.thread;
/*
* 生产者消费者问题
* */
public class ProducerConsumer {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Basket basket = new Basket();
Producer p1 = new Producer(basket); //new 一下生产者
Producer p2 = new Producer(basket); //new 一下生产者
Consumer c1 = new Consumer(basket); //new 一个消费者
Thread t1, t2, t3;
t1 = new Thread(p1);
t2 = new Thread(p2);
t3 = new Thread(c1);
t1.setName("Producer p1");
t2.setName("Producer p2");
t3.setName("Consumer c1");
t1.start();
t2.start();
t3.start();
}
}
//面包类,模拟篮子中的食品
class Bread {
int ID; //ID of one bread
Bread(int ID) {
this.ID = ID;
}
}
//篮子类,用于模拟缓冲池
class Basket { //使用的是顺序栈的技术,通过下标控制入栈和出栈
Bread[] breadArr = new Bread[6]; //bared array,篮子中最多装6个食物
int index; //下标用来标记当前的食物数
Basket() { //初始化篮子为空,即下标为0
index = 0;
}
public synchronized void push(Bread bread) { //向篮子中放入食物的方法,这是一个互斥的方法,一个进程在使用的时候其它对象不能访问
while(index == (breadArr.length - 1)) { //当篮子中的食物已经满了的时候,线程进入等待状态并叫醒其它正在等待的消费者
try {
this.wait(); //进入等待状态,并释放了对push方法的锁定,其它的线程可以继续使用此方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notify(); //唤醒其它正在等待的消费者线程
breadArr[index] = bread; //把面包放入篮子中
// System.out.println("Produce: " + index);
index++; //食物的数量加1
}
public synchronized void pop() {
while(index == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.notifyAll();
index--;
// System.out.println("Consume" + index);
}
}
//生产者类,向篮子中放入食物
class Producer implements Runnable {
Basket basket;
Producer(Basket basket) { //生产者构造方法,确定向哪一个篮子中放入食物
this.basket = basket;
}
public void run() {
for(int i = 0; i < 100; i++) { //每个生产者进行100次生产
Bread bread = new Bread(i);
basket.push(bread);
//每生产一个食物就打印出是谁生产了食物,以及是他生产的第几个食物
System.out.println(Thread.currentThread().getName() + " produce a bread" + i);
try {
Thread.sleep((int)Math.random() * 200); //生产者每生产一个食物就睡随机的一段时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//消费者,从篮子中取出食物
class Consumer implements Runnable {
Basket basket;
Consumer(Basket basket) { //消费者构造方法,从哪一个篮子中取出食物
this.basket = basket;
}
public void run() {
for(int i = 0; i < 200; i++) { //每个消费者进行200次消费(因为创建了两个生产者只有一个消费者)
basket.pop();
//每消费一个食物就打印出是谁消费了食物,以及是他消费的第几个食物
System.out.println(Thread.currentThread().getName() + " consume a bread" + i);
try {
Thread.sleep((int)Math.random() * 1000); //消费者线程每消费一个食物就睡随机的时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Java实现生产者消费者问题
最新推荐文章于 2021-02-12 19:55:29 发布