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

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

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

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

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

发布了82 篇原创文章 · 获赞 26 · 访问量 3988

猜你喜欢

转载自blog.csdn.net/qq_40742223/article/details/104694830
今日推荐