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

什么是多线程的生产者-消费者问题
当一个或者多个线程只负责往"数据缓冲区"中添加数据,而一个或者多个线程只负责从"数据缓冲区"中 取数据时可能造成的存数据时数据缓冲区满,或者取数据时,数据缓冲区为空的情况,这种情况就称为生产者-消费者问题.

而线程通信,就是在遇到"生产者-消费者问题"的时候需要用到的
生产者-消费者问题
(1)因为生产者-消费者都要操作数据缓冲区,所以数据缓冲区是共享的,就会可能造成线程通信问题.
(2)因为数据缓冲区的大小是有限的,所以就需要线程通信,就要用到wait和notify方法.
注意用wait和notify方法都需要用"同步锁"对象调用

如果用"非同步锁"对象调用wait和notify方法,会报错

一个案例:
厨师负责炒菜,炒好的菜放在工作台上,服务员负责给客户上菜,每次都要从工作台上取菜.工作台上能存储的菜的数量最大为10.

public class TestCommunicate {
	public static void main(String[] args) {
		//创建工作台
		WorkBench w= new WorkBench();
		//创建厨师
		Cook c = new Cook(w);
		Waiter t = new Waiter(w);
		//启动线程
		c.start();
		t.start();
	}

}
//因为要保证Cook和Waiter使用的是同一个WorkBench的对象,我们用传参数的方式
class  Cook extends Thread{
	//要使用WorkBench类中的方法:
	//(1)使用静态
	//(2)传递对象
	
	private   WorkBench w;
	public Cook(WorkBench w) {
		super();
		this.w =w;
		
	}
	public void run() {
		while(true) {
			try {
				Thread.sleep(90);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			w.put();
		}
	}
}
class Waiter extends  Thread{
	private   WorkBench w;
	public Waiter(WorkBench w) {
		super();
		this.w= w;
		
	}
	public void run() {
		while(true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
			w.take();
		}
	
	}
	
}
//模拟厨师出菜窗口
class WorkBench{
	//假设最多放10个菜
	private static final int MAX_VALUE =10;
	//num记录放的菜的数量
	private int num;
	
	public synchronized void take() {
		if(num<=0) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		num--;
		System.out.println("服务员拿走了一份菜剩余"+num);
		this.notify();
	}
	public synchronized void put() {
		if(num>=MAX_VALUE) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		num++;
		System.out.println("厨师又炒好了一份菜剩余"+num);
		this.notify();
	}
	
}

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

猜你喜欢

转载自blog.csdn.net/qq_40742223/article/details/104691068