Java生产者与消费者问题

/*
 * 线程通信是用来解决生产者与消费者问题。
 * 
 * 生产者与消费者问题:
 * 	  有两个或者多个线程。
 * 	 其中一个/一部分线程,生产“数据”,称为生产者线程;
 * 	另一个/一部分线程,消耗“数据”,称为消费者线程。
 * 	这些数据放在一个“共享”区域。
 *  那么就会出现:
 *    当“共享”区域中的数据空了,消费者线程必须"停/等待",等待到产者线程生产了新数据后,继续进行。
 *    当“共享”区域中的数据满了,生产者线程必须"停下/等待",等到消费者线程消耗了数据后,继续进行。
 *    
 *  生产者与消费者问题:
 *  (1)共享数据:    就会有线程安全问题,就需要同步
 *  (2)共享区域大小固定,有限的:就需要用到“协作”,线程通信。
 *  
 *  Object类中有:
 *  (1)wait():必须由锁对象(线程的监视器对象)来调用。
 *  (2)notify():必须由锁对象(线程的监视器对象)来调用。
 *  notify()作用就是唤醒一个正在等待的线程。唤醒的是同一个锁对象监视的等待线程。
 */
public class Test14 {
	public static void main(String[] args) {
		Workbench tai = new Workbench();
		
		Cook c = new Cook("崔志恒", tai);
		Waiter w = new Waiter("翠花", tai);
		
		c.start();
		w.start();
	}
}
class Workbench{
	//假设工作台上最多能够放10盘
	private static final int MAX = 10;
	private int count;
	
	//同步方法,非静态方法来说,锁对象就是this
	public synchronized void put(){//往工作台上放一盘菜
		if(count >= MAX){
			try {
				//生产者停下来,等待
				wait();//默认是this.wait()
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		count++;
		
		System.out.println(Thread.currentThread().getName() + "放了一盘菜,剩余:" + count);
		this.notify();
	}
	
	public synchronized void take(){//从工作台上取走一盘菜
		if(count<=0){
			try {
				//工作台没有菜,消费者应该停下来
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		count--;
		System.out.println(Thread.currentThread().getName() + "取走一盘菜,剩余:" + count);
		this.notify();
	}
}
class Cook extends Thread{
	private Workbench tai;

	public Cook(String name, Workbench tai) {
		super(name);
		this.tai = tai;
	}

	public void run(){
		while(true){
			tai.put();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
class Waiter extends Thread{
	private Workbench tai;
	
	public Waiter(String name, Workbench tai) {
		super(name);
		this.tai = tai;
	}

	public void run(){
		while(true){
			tai.take();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
/*
 * 线程通信是用来解决生产者与消费者问题。
 * 
 * 生产者与消费者问题:
 * 	  有两个或者多个线程。
 * 	 其中一个/一部分线程,生产“数据”,称为生产者线程;
 * 	另一个/一部分线程,消耗“数据”,称为消费者线程。
 * 	这些数据放在一个“共享”区域。
 *  那么就会出现:
 *    当“共享”区域中的数据空了,消费者线程必须"停/等待",等待到产者线程生产了新数据后,继续进行。
 *    当“共享”区域中的数据满了,生产者线程必须"停下/等待",等到消费者线程消耗了数据后,继续进行。
 *    
 *  生产者与消费者问题:
 *  (1)共享数据:    就会有线程安全问题,就需要同步
 *  (2)共享区域大小固定,有限的:就需要用到“协作”,线程通信。
 *  
 *  Object类中有:
 *  (1)wait():必须由锁对象(线程的监视器对象)来调用。
 *  (2)notify():必须由锁对象(线程的监视器对象)来调用。
 *  notify()作用就是唤醒一个正在等待的线程。唤醒的是同一个锁对象监视的等待线程。
 *  (3)notifyAll():唤醒所有和我是同一个监视器对象的正在等待的线程
 */
public class Test16 {
	public static void main(String[] args) {
		Workbench tai = new Workbench();
		
		Cook c1 = new Cook("崔志恒", tai);
		Cook c2 = new Cook("甄玉禄", tai);
		Waiter w1 = new Waiter("翠花", tai);
		Waiter w2 = new Waiter("如花", tai);
//		Waiter w3 = new Waiter("秋香", tai);
		
		c1.start();
		c2.start();
		w1.start();
		w2.start();
//		w3.start();
	}
}
class Workbench{
	//假设工作台上最多能够放10盘
	private static final int MAX = 1;
	private int count;
	
	//同步方法,非静态方法来说,锁对象就是this
	public synchronized void put(){//往工作台上放一盘菜
		while(count >= MAX){
			try {
				//生产者停下来,等待
				wait();//默认是this.wait()
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		count++;
		System.out.println(Thread.currentThread().getName() + "放了一盘菜,剩余:" + count);
		this.notify();
	}
	
	public synchronized void take(){//从工作台上取走一盘菜
		while(count<=0){
			try {
				//工作台没有菜,消费者应该停下来
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		count--;
		System.out.println(Thread.currentThread().getName() + "取走一盘菜,剩余:" + count);
//		this.notify();
		this.notifyAll();
	}
}
class Cook extends Thread{
	private Workbench tai;

	public Cook(String name, Workbench tai) {
		super(name);
		this.tai = tai;
	}

	public void run(){
		while(true){
			tai.put();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
class Waiter extends Thread{
	private Workbench tai;
	
	public Waiter(String name, Workbench tai) {
		super(name);
		this.tai = tai;
	}

	public void run(){
		while(true){
			tai.take();
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值