Java 监视器对象在同步块中有什么影响?

Java 监视器对象在同步块中有什么影响?,java,synchronization,thread-safety,locking,synchronized-block,Java,Synchronization,Thread Safety,Locking,Synchronized Block,经过几个小时的阅读,我仍在努力理解监视器对象的确切功能 演示我的意思: 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")))

经过几个小时的阅读,我仍在努力理解监视器对象的确切功能

演示我的意思:

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");
    }   
}
公共类演示{
公共静态浴室=新浴室();
公共静态厨房=新厨房();
公共静态void main(字符串[]args){
(新线程(新室友(“bob”)).start();
(新线程(新室友(“约翰”))。开始();
(新线程(新Mom()).start();
}
}
班级浴室{
公共无效使用(字符串who){
同步(演示厨房){
System.out.println(谁+“正在使用浴室”);
长时间=System.currentTimeMillis();
而(System.currentTimeMillis()-时间<2000){
继续;
}
System.out.println(who+“解锁浴室”);
}
}
}
班级厨房{
同步的公共void使用(字符串who){
System.out.println(谁+“正在使用厨房”);
}
}
班级室友实现Runnable{
私有字符串名称;
公共室友(字符串名称){this.name=name;}
@凌驾
公开募捐{
演示。浴室。使用(名称);
}   
}
类Mom实现了Runnable{
@凌驾
公开募捐{
演示。厨房。使用(“妈妈”);
}   
}
我把“Demo.kitchen”放在浴室同步区的括号里。如果有人使用浴室,那么浴室和厨房都是锁着的。为什么他们都锁着

我猜:

1) 监视器对象本身(在我的例子中是厨房)被锁定到所有线程(在同步块中使用时)

2) 如果他们都有相同的监视器对象,一次只允许一个线程执行同步块(在我的例子中,两个室友都有相同的浴室作为监视器对象)

这是正确的想法还是我遗漏了什么? Marko Topolnik,谢谢你的回答

我想我知道现在发生了什么

First thread1(bob)开始使用浴室并锁定厨房(因为提供了Demo.kitchen)。 当约翰也想用浴室时,他不能用,不是因为浴室锁着,而是因为他正在检查厨房是否锁着(鲍勃刚刚锁上了)。
妈妈不能使用厨房,因为那是实际锁定的对象。

小心不要将监视器与它们所属的对象混淆。通常,在考虑监视器和锁时,最好完全忘记“对象”方面

特别是,声明某段代码的类与获取的锁无关。在
浴室
的方法中锁定
Demo.kitchen
时,仅锁定
kitchen
对象。此外,锁定
Demo.kitchen
不会阻止其他代码同时访问和更改
kitchen
对象,除非该代码也受同一锁的保护。

另请参见: