举个很简单的例子,厨师和吃客,厨师做出一道菜,吃客吃一道菜;按常理推,菜的数量应为锁,从而操作线程唤醒或等待,但事实是food不能成为synchronized
的参数,必须在Desk
中定义一个Object lock
并传入synchronized
,程序才能跑的通,很疑惑,请大神解答!
正确代码如下,错误代码放在注释中。
//餐桌
public class Desk {
public static Integer food = 0;// 食物,1代表有食物,0代表无食物
public static Object lock = new Object();
}
厨师类
public class Cook extends Thread {
@Override
public void run() {
synchronized (Desk.lock) {//这里必须使用Object类对象,而使用Desk.food就报错
while (true) {
if (Desk.food == 1) {
try {
Desk.lock.wait();//这里必须用lock对象,而使用Desk.food就报错
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {
Desk.food += 1;
System.out.println("厨师做菜" + Desk.food);
Desk.lock.notifyAll();//唤起消费者线程,这里必须用lock对象,而使用Desk.food就报错
}
}
}
}
}
吃客类
public class Foodie extends Thread {
@Override
public void run() {
synchronized (Desk.lock) {//这里必须使用Object类对象,而使用Desk.food就报错
while (true) {
if (Desk.food == 0) {
try {
Desk.lock.wait();//当前线程等待,这里必须用lock对象,而使用Desk.food就报错
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else {
Desk.food -= 1;
System.out.println("我吃了" + Desk.food);
Desk.lock.notifyAll();//唤起厨师线程,这里必须用lock对象,而使用Desk.food就报错
}
}
}
}
}
main方法
public static void main(String[] args){
Cook cook =new Cook();
Foodie foodie = new Foodie();
Thread c = new Thread(cook,"厨师线程");
Thread f = new Thread(foodie,"消费者线程");
c.start();
f.start();
}
设想这样一个场景: