锁和嵌套的同步方法

时间:2012-05-30 22:24:49

标签: java methods nested synchronized locks

说我们有类似的东西,

class Class{    
//...
synchronized void m1(Class obj){ obj.m2(); }
synchronized void m2(){ /*...*/ }
}

我的问题 - 什么时候锁定对象obj?当它从方法m2返回时,或方法m1?

2 个答案:

答案 0 :(得分:3)

来自JLS Section 17

  

线程t可能会多次锁定特定监视器;每次解锁都会逆转一次锁定操作的效果。

但是,由于m1()m2()可能会锁定不同的对象,因此您的问题很复杂。 m1()会锁定您调用它的任何对象,而这些对象尚未显示。所以事件的顺序是:

  1. 您调用x.m1(y) xy可能是Class的不同实例。
  2. 在输入m1之前,JVM会将监视器锁定为x
  3. m1调用m2
  4. 在输入m2之前,JVM将监视器锁定为y
  5. 退出m2时,y的监视器已发布
  6. 退出m1时,x的监视器已发布
  7. 如果xy是同一个对象,则会在m1退出时释放锁定。

答案 1 :(得分:1)

尝试翻译同步块中的synchronized方法:

m1(C obj) {
    synchronized(this) {
        obj.m2();
    }
}

m2() {
    synchronized(this) {
        // some stuff
    }
}

因此,您的obj对象仅在m2()来电期间被锁定。这是因为这是this转换为obj的唯一时间。

m1()调用仅锁定当前对象,顺便说一下,该对象也可以是obj;如果是这种情况(第一次调用中为this == obj),那么obj将被锁定,直到m1()m2()完成。