Java 具有synchronized语句的可重入同步行为

Java 具有synchronized语句的可重入同步行为,java,Java,我在一个java类中有两个方法,它们都有一个使用同一对象进行同步的代码块。我知道在JAVA同步方案中,线程获取的锁是可重入的。有了这一点,我可以放心地说下面的代码不会在所有情况下导致任何问题吗 public class Someclass { private static final Object LCK_OBJ = new Object(); //..... publc void method1() { //some code....

我在一个java类中有两个方法,它们都有一个使用同一对象进行同步的代码块。我知道在JAVA同步方案中,线程获取的锁是可重入的。有了这一点,我可以放心地说下面的代码不会在所有情况下导致任何问题吗

public class Someclass  
{  
  private static final Object LCK_OBJ = new Object();  
  //.....

  publc void method1()  
  {  
    //some code....  
    synchronized(LCK_OBJ)  
    {  
        //some sychronized code.  
        method2(..);  
    }  
    //some more code....  
  }  

  protected static final void method2(..)  
  {  
      Someclass ref = null;  
      //some code which gets different other references of SomeClass in a loop....  
      ref.method3(..);  
  }  

  publc void method3()  
  {  
    //some code....  
    synchronized(LCK_OBJ)  
    {  
      //some sychronized code.  
    }  
    //some more code....  
  }  

}//end of class    

是的,同一线程可以多次在同一个锁上输入
synchronized
块。小心不要以不同的顺序获取其他锁,否则会导致死锁。

是的,同步块是可重入的。ReentrantLock也是可重入的,如果您想自己编写代码块,您可能希望使用它,因为它具有更高的灵活性/功能性

我会确保任何锁都是final的,如果一个锁对象不能是final的,那么它几乎肯定是一个bug(或者一个混乱的来源)


出于比较目的,并非Java中的所有锁都是可重入的。FileLock并不是直接将请求传递给操作系统。是的,您可以,但此代码不会编译:您正在从静态方法“method2”调用实例方法“method3”。除此之外:如果线程在“Mult1”中锁定了锁,如果在“Mult3”中仍然有锁。

< P>尽管这个代码不会像前面提到的那样编译,但请考虑Mault2不是静态的情况。从方法1到方法2,然后到方法3的调用是可重入同步的一个很好的例子。它创建了一个新堆栈,run()位于堆栈底部。由于对method1的调用来自run(),因此它被添加到run()上方的堆栈中,然后进入堆栈中的method2和method3。此外,由于对象锁由堆栈上的method2获取,因此在所有调用的同步api上都会保持锁。释放锁的方法是打开堆栈中最顶层的方法(本例中为method3),直到达到调用synchronize的实际api为止。

@Stephen C,我的观点是,您可以相信Java中的所有锁都是可重入的。感谢您对该行为的确认。在最后一个修饰符上,您是对的……实际上,当我在键入示例代码时遗漏了它,这是我的一个疏忽,尽管我是认真的(注意all caps变量名)。很抱歉,再次感谢。谢谢你,托马斯斯坦扎克!在键入示例代码时,我没有通过对象引用键入实例方法调用。对此表示抱歉&感谢您的回复。如果有其他线程在method2(从method1调用)中执行同步代码时,试图在method1或method3中执行同步代码,我们可以确定第二个线程将被阻塞,直到第一个线程完成method1、method2和method3的执行吗,它将阻塞直到释放锁,当第一个线程从method3和method2返回后离开method1中的同步块时,就会发生这种情况。