多线程_生产者消费者问题
什么是多线程的生产者-消费者问题
当一个或者多个线程只负责往"数据缓冲区"中添加数据,而一个或者多个线程只负责从"数据缓冲区"中 取数据时可能造成的存数据时数据缓冲区满,或者取数据时,数据缓冲区为空的情况,这种情况就称为生产者-消费者问题.
而线程通信,就是在遇到"生产者-消费者问题"的时候需要用到的
生产者-消费者问题
(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();
}
}