生产者消费者模型(java多线程)
项目实例
/**
* 面包对象
*/
public class Bread {
}
public class BreadContainer {
//面包柜容量
private Bread[] breads;
//当前面包数量
private int size=0;
//初始化面包柜容量
public BreadContainer(int initSize) {
breads = new Bread[initSize];
}
//添加面包
public synchronized void add(Bread bread) throws InterruptedException {
//循环判断面包柜是否满 满就等待
while (size == breads.length){
System.out.println("面包柜已满...");
wait();//线程等待
}
breads[size++]=bread;//添加一个面包
System.out.println(Thread.currentThread().getName()+"生产第"+size+"个面包");
notifyAll();//每添加一次面包就去唤醒所有的销售者
Thread.sleep(10);//模仿延迟
}
//销售面包
public synchronized void remove() throws InterruptedException {
//如果size=0 代表面包柜为空了 就等待
while (size == 0){
System.out.println("面包卖完了-----");
wait();
}
System.out.println(Thread.currentThread().getName()+"卖了第"+size+"个面包");
breads[--size]=null;//卖掉一个面包
notifyAll();//每卖掉一个面包就去唤醒所有的面包厨师
Thread.sleep(10);//模仿延迟
}
}
public class 生产者消费者 {
public static void main(String[] args) {
//创建面包柜对象
BreadContainer breadContainer = new BreadContainer(10);
//创建生产者线程(1号面包师) 假如师傅一天只做20个面包
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i=0;i<20;i++) {
//面包对象
Bread bread = new Bread();
try {
//放入面包柜
breadContainer.add(bread);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t1.setName("面包师1");
//创建消费者线程(1号销售员)
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 20; i++) {
try {
//从面包柜卖出
breadContainer.remove();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t2.setName("1号销售员");
//线程启动
t1.start();
t2.start();
}
}
wait()
详细wait():
1.wait()是Object里面的方法,而不是Thread里面的。作用是将当前线程置于预执行队列,并在wait()所在的代码处停止,等待唤醒通知。
2.wait()只能在同步代码块或者同步方法中执行,如果调用wait()方法,而没有持有适当的锁,就会抛出异常。
wait()方法调用后悔释放出锁,线程与其他线程竞争重新获取锁
notifyAll() :