我在教程中看到了这一点,他们询问以下代码是否存在问题。对我来说,看起来像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");
}
}
答案 0 :(得分:3)
不,该代码没有问题。 请注意两件事:
synchronized SomeType foo() { ... }
相当于
SomeType foo() {
synchronized (this) { ... }
}
它锁定封闭类的this
实例。因此,在您的情况下a()
和b()
锁定相同的内容
如果一个线程已经在某个对象的监视器上持有一个锁,它会阻止另一个线程获取同一个对象的锁,但是同一个线程可以获得更多的锁,如果它也需要,也不会受到影响。所以
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)
不,你不对。 线程可以控制监视器,而不是方法,因此它可以跟随执行,并根据需要在同一对象上同步多个方法。