Java实现生产者消费者问题

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值