java线程生产者和消费者问题

package thread;

/*
 * 馒头类
 */
class ManTou{
	//馒头id
	private int id;
	
	public ManTou(int id){
		this.id = id;
	}

	@Override
	public String toString() {
		return "ManTou [id=" + id + "]";
	}
}

/*
 * 生产者和消费者的栈  先生产的馒头后吃 先进后出
 */
class SyncStack{
	//当前馒头的索引
	private int index = 0;
	
	//盛放馒头的框 最多生产5个馒头
	private ManTou[] array = new ManTou[5];
	
	//线程同步加馒头 一个线程在加馒头的时候 别的线程需要排队
	synchronized void push(ManTou manTou){
/*if*/while(index == array.length && array.length == index){
			//System.out.println("满了");
			//如果当前要生产馒头的人发现馒头满了 如果return 这个人这个人生产的馒头就作废了,
			//可能导致几个人吃不到馒头,
//			return;	
			
			//所以正确的方法是等着等到放馒头的栈没满的时候再做馒头
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		//如果发现当前对象上有正在睡着的线程就叫醒他 让他不要再等了 接着排队做馒头 叫醒自己  
		this.notify();
		
		//叫醒这个对象上所有正在睡着的线程
		//this.notifyAll();
		
		System.out.println("生产了:" + manTou);
		
		array[index] = manTou;
		index++;
	}
	
	//线程同步方法  线程必须 排队吃馒头  (一个线程吃着馒头别的线程要只能看着)
	synchronized ManTou get(){
		//这个位置判断是不是吃没了为什么不用if 而用while,
		//因为当前线程醒过来的时候 他不一定 有馒头吃 说不定此时馒头刚好被另一个线程吃完了
		//必须要当前线程被叫醒后 要 不断的去判断自己现在的馒头数是否有的吃 
		//如果有才可以吃  不然 馒头吃完了到0了 接着往下 0-- = -1 就越界了
/*if*/while(index == 0){

			//System.out.println("吃没了");
//			return null;
			
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		this.notify();
		
		index--;
		System.out.println("消费了:" + array[index]);
		
		return array[index];
	}
}

/*
 * 生产者类 生产馒头
 */
class Producer implements Runnable{
	private SyncStack syncStack = null;
	
	public Producer(SyncStack syncStack){
		this.syncStack = syncStack;
	}
	
	@Override
	public void run() {
		for(int i = 0;i < 20;i++){
			syncStack.push(new ManTou(i));	//加馒头
			try {
				Thread.sleep((int)(Math.random() * 1000));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

/*
 * 消费者类 吃馒头
 */
class Consumer implements Runnable{
	private SyncStack syncStack = null;
	
	public Consumer(SyncStack syncStack){
		this.syncStack = syncStack;
	}
	
	@Override
	public void run() {
		for(int i = 0;i < 20;i++){
			syncStack.get();	//吃馒头
			try {
				Thread.sleep((int)(Math.random() * 1000));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

public class ThreadProducerConsumer {
	/**
	 * 线程 生产者和消费者问题
	 */
	public static void main(String[] args) {
		SyncStack syncStack = new SyncStack();
//		
//		for(int i = 0;i < 20;i++){
//			syncStack.push(new ManTou(i));
//		}
//		
//		System.out.println(syncStack.array);
//		
//		for(int i = 0;i < 20;i++){
//			syncStack.get();
//		}
//		
//		System.out.println(syncStack.array);
//		
//		for(int i = 10;i < 20;i++){
//			syncStack.push(new ManTou(i));
//		}
//		
//		System.out.println(syncStack.array);
		
		Producer producer = new Producer(syncStack);
		Consumer consumer = new Consumer(syncStack);
		
		new Thread(producer).start();
		new Thread(producer).start();
		new Thread(producer).start();
		new Thread(consumer).start();
		new Thread(consumer).start();
		new Thread(consumer).start();
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值