代码示例:
import java.util.Random;
public class Productor implements Runnable{
private String[] foods;
private Disk disk;
private Random ram = new Random();
public String[] getFoods() {
return foods;
}
public void setFoods(String[] foods) {
this.foods = foods;
}
public Disk getDisk() {
return disk;
}
public void setDisk(Disk disk) {
this.disk = disk;
}
public Productor(Disk disk) {
this.disk = disk;
this.foods = new String[]{"红烧牛肉面", "新疆拌面", "山西刀削面", "陕西油泼面", "羊肉泡馍", "土豆丝", "湘菜"};
}
@Override
public void run() {
// 生成30次食物
for (int i = 0; i < 30; i++) {
makeFood();
}
}
private void makeFood() {
// 注意,钥匙必须是共有对象
synchronized (this.disk) {
if (!disk.isEmpty()) {
// 生成食物
int index = ram.nextInt(foods.length);
String food = foods[index];
System.out.println(Thread.currentThread().getName() +"生产了"+ food + "食物");
disk.setFood(food);
disk.setEmpty(true);
// 使用共用对对象
// 唤醒其他拥有盘子的对象
disk.notify();
try {
// 让生产者等待消费者消费
disk.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
disk.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Cumstor implements Runnable {
private Disk disk;
public Cumstor(Disk disk) {
this.disk = disk;
}
@Override
public void run() {
while(true) {
eat();
}
}
private void eat() {
synchronized (this.disk) {
if (disk.isEmpty()) {
System.out.println(Thread.currentThread().getName()+ "吃掉了"+ disk.getFood() +"食物");
disk.setEmpty(false);
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
disk.notify();
try {
disk.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
disk.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Disk {
private String food;
private boolean empty;
public String getFood() {
return food;
}
public void setFood(String food) {
this.food = food;
}
public boolean isEmpty() {
return empty;
}
public void setEmpty(boolean empty) {
this.empty = empty;
}
public static void main(String[] args) {
Disk d = new Disk();
Productor p = new Productor(d);
Cumstor c = new Cumstor(d);
Thread t1 = new Thread(p, "王大锤");
Thread t2 = new Thread(c, "张全蛋");
// t2 做成守护线程
t2.setDaemon(true);
t1.start();
t2.start();
}
}
生产者消费者问题:
上述代码运行时发现严重的问题:
加入同步后又有了新问题产生了。
问题2:发现了连续生产却没有消费,同时对同一个商品进行多次消费。希望的结果时生产一个商品,就被消费者吃掉。生产下一个商品。搞清楚几个问题?生产者什么时候生产呢?消费者什么时候应该消费呢?
当容器中没有面包,就生产,如果有面包,就不要生产了。
当容器中已有面包时,就消费,如果没有面包,就不要消费。
通过等待唤醒机制:解决 生产消费者问题: