【问题标题】:Java locks with synchronized keyword带有 synchronized 关键字的 Java 锁
【发布时间】:2023-07-05 00:18:01
【问题描述】:

我在教程中看到了这个,他们问下面的代码是否有问题。对我来说,看起来 b() 无法访问,因为 a() 已经控制了监视器。我这样想对吗?

public class Test {
    public synchronized void a() {
        b();
        System.out.println("I am at a");
    }
    public synchronized void b() {
        System.out.println("I am at b");
    }
}

【问题讨论】:

  • 有人在没有任何解释的情况下投了反对票?我也不知道答案,介意解释一下吗??
  • 我不知道投反对票的原因,但似乎 OP 不只是尝试。

标签: java synchronize


【解决方案1】:

不,该代码没有问题。 注意两点:

  1. synchronized SomeType foo() { ... } 等价于

    SomeType foo() {
        synchronized (this) { ... } 
    }
    

    它锁定封闭类的this 实例。所以,在你的情况下,a()b() 锁定的是同一个东西

  2. 如果一个线程已经在某个对象的监视器上持有一个锁,它会阻止另一个线程获取同一个对象上的锁,但是如果它也需要,同一个线程可以获得更多的锁,这不受影响。所以

    public synchronized void a() {  // acquires lock on this
       b();                         // also aquires lock on this, but it's ok because it is the same thread
       System.out.println("I am at a");
    }      
    

    当一个线程在a() 中时,没有其他线程能够在同一个实例上调用a()b()。如果他们尝试这样做,他们将不得不等到当前线程退出a()。但是当前线程本身不受影响,它可以调用这个对象上的任何同步方法,因为它已经持有锁了。

【讨论】:

    【解决方案2】:

    不,你错了。 线程 控制了监视器,而不是方法,因此它能够根据需要在同一个对象上同步执行尽可能多的方法。

    【讨论】: