Java使用synchronized关键字锁定

时间:2014-12-14 02:05:18

标签: java synchronize

我在教程中看到了这一点,他们询问以下代码是否存在问题。对我来说,看起来像b()无法访问,因为()已经拥有对监视器的控制权。我这么想是对的吗?

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");
    }
}

2 个答案:

答案 0 :(得分:3)

不,该代码没有问题。 请注意两件事:

  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()。但是当前线程本身不受影响,它可以调用此对象上的任何同步方法,因为它已经持有锁。

答案 1 :(得分:0)

不,你不对。 线程可以控制监视器,而不是方法,因此它可以跟随执行,并根据需要在同一对象上同步多个方法。