经过几个小时的阅读后,我仍在努力了解显示器对象的确切功能。
显示我的意思的演示:
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&#39;进入浴室同步区块的括号。如果有人在使用浴室,那么浴室和厨房都会被锁上。为什么他们都被锁定了?
我在猜测:
1)监视器对象本身(在我的情况下是厨房)被锁定到所有线程(当它在同步块中使用时)
2)如果它们都有相同的监视器对象,那么一次只允许一个线程执行同步块(在我的情况下,两个室友都有与监视器对象相同的浴室)
Marko Topolnik,谢谢你的回答。
我想我明白现在发生了什么。
第一个thread1(bob)开始使用浴室并锁定厨房(因为提供了Demo.kitchen)。 当约翰也想要使用浴室时他不能,但不是因为浴室已被锁定,而是因为他正在检查厨房是否锁定(并且鲍勃只是将其锁定)。 而且妈妈不能使用厨房,因为这是实际锁定的对象。
答案 0 :(得分:0)
小心不要将监视器与其所属的对象混淆。通常,在考虑监视器和锁定时,最好完全忘记“对象”方面。
特别是,声明某段代码的类与获取的锁无关。当您在Demo.kitchen
的方法中锁定Bathroom
时,只会锁定kitchen
个对象。此外,锁定Demo.kitchen
不会阻止其他代码同时访问和更改kitchen
对象 - 除非该代码也受同一锁的保护。