多线程_多个生产者多个消费者问题

多线程中多个生产者多个消费者问题

还是之前的问题:厨师负责做菜,服务员负责给客人上菜,厨师做好的菜放在工作台上,服务员从工作台上取菜品,但是这次的厨师和服务员都有多个.

首先创建出多个厨师和多个服务员是很简单的,为了方便,我们给线程重命名一下,做一个标记,在后面方便进行观察.

public class TestCommunicate {
	public static void main(String[] args) {
		//创建工作台
		WorkBench w= new WorkBench();
		//创建厨师
		Cook c1 = new Cook(w,"厨师1");
		Cook c2 = new Cook(w,"厨师2");

		Waiter t1 = new Waiter(w,"服务员1");
		Waiter t2 = new Waiter(w,"服务员2");
		Waiter t3 = new Waiter(w,"服务员3");
	
		//启动线程
		c1.start();
		c2.start();
		
		t1.start();
		t2.start();
		t3.start();
	}

}
//因为要保证Cook和Waiter使用的是同一个WorkBench的对象,我们用传参数的方式
class  Cook extends Thread{
	//要使用WorkBench类中的方法:
	//(1)使用静态
	//(2)传递对象
	
	private   WorkBench w;
	public Cook(WorkBench w,String name) {
		super(name);
		this.w =w;
		
	}
	public void run() {
		while(true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			w.put();
		}
	}
}
class Waiter extends  Thread{
	private   WorkBench w;
	public Waiter(WorkBench w,String name) {
		super(name);
		this.w= w;

		
	}
	public void run() {
		while(true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			w.take();
		}
	
	}
	
}

下面是工作台的功能设计,我们要解决的问题是:
(1)厨师和服务员都有多个,我们在厨师做菜和服务员取菜时,怎么能让线程在数据处理的时候不发生错误.
(2)notify()方法唤醒线程,是随机唤醒的,要防止线程的循环等待.

class WorkBench{
	//假设最多放10个菜
	private static final int MAX_VALUE =10;
	//num记录放的菜的数量
	private int num;
	
	
	//在多个厨师多个服务员的条件下,如果;
	//(1)厨师还没有做菜,服务员1wait服务员2wait服务员3wait
	//(2)厨师做了一份菜,因为notify是随机唤醒一个线程,我们假设唤醒的是服务员1,那么num==1,执行之后还有一个notify,这时候
	//虽然num==0,服务员2还是被唤醒了,结果执行了后面的num--和notify并唤醒了服务员3
	//这就会造成错误,我们需要在服务员1唤醒服务员2之后,再判断num的值,考虑是否执行num--的操作.因此将if改为while
	public synchronized void take() {
		
		//
		while(num<=0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		num--;
		System.out.println("服务员"+Thread.currentThread().getName()+"拿走了一份菜剩余"+num);
		this.notifyAll();
	}
	public synchronized void put() {
		while(num>=MAX_VALUE) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		num++;
		System.out.println("厨师"+Thread.currentThread().getName()+"又炒好了一份菜剩余"+num);
		this.notifyAll();
	}
	
}

全部评论

相关推荐

沉淀一会:**圣经 1.同学你面试评价不错,概率很大,请耐心等待;2.你的排名比较靠前,不要担心,耐心等待;3.问题不大,正在审批,不要着急签其他公司,等等我们!4.预计9月中下旬,安心过节;5.下周会有结果,请耐心等待下;6.可能国庆节前后,一有结果我马上通知你;7.预计10月中旬,再坚持一下;8.正在走流程,就这两天了;9.同学,结果我也不知道,你如果查到了也告诉我一声;10.同学你出线不明朗,建议签其他公司保底!11.同学你找了哪些公司,我也在找工作。
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务