经过数小时的阅读,我仍在努力理解监视器对象的确切作用。
演示我的意思:
public class Demo {
public static Bathroom bathroom = new Bathroom();
public static Kitchen kitchen = new Kitchen();
public static void main(String[] args) {
(new Thread(new Roommate("bob"))).start();
(new Thread(new Roommate("john"))).start();
(new Thread(new Mom())).start();
}
}
class Bathroom {
public void use(String who) {
synchronized (Demo.kitchen) {
System.out.println(who + " is using bathroom");
Long time = System.currentTimeMillis();
while (System.currentTimeMillis() - time < 2000) {
continue;
}
System.out.println(who + " unlocked bathroom");
}
}
}
class Kitchen {
synchronized public void use(String who) {
System.out.println(who + " is using kitchen");
}
}
class Roommate implements Runnable {
private String name;
public Roommate (String name) { this.name = name; }
@Override
public void run() {
Demo.bathroom.use(name);
}
}
class Mom implements Runnable {
@Override
public void run() {
Demo.kitchen.use("mom");
}
}
我将“Demo.kitchen”放在浴室同步块的括号中。如果有人在使用浴室,那么浴室和厨房都被锁定。为什么两个都被锁了?
我猜想:
1)监视器对象本身(在我的例子中是厨房)被锁定到所有线程(在同步块中使用时)
2)如果它们都具有相同的监视器对象(在我的情况下,两个室友的浴室与监视器对象相同),则一次只允许一个线程执行同步块
这是正确的想法还是我错过了什么?
Marko Topolnik,谢谢你的回答。
我想我明白现在发生了什么。
第一个线程 1 (bob) 开始使用浴室并锁定厨房(因为提供了 Demo.kitchen)。当 john 也想使用浴室时,他不能,不是因为浴室被锁定,而是因为他正在检查厨房是否被锁定(鲍勃刚刚锁定它)。而妈妈不能使用厨房,因为那是实际上被锁定的物体。