美文网首页
synchronized实现原理

synchronized实现原理

作者: cbhe | 来源:发表于2020-05-25 21:08 被阅读0次

    synchronize可以修饰方法、代码块
    当修饰代码块的时候其原理就是在编译时在代码块对应的字节码的上下分别增加monitorenter和moniterexit字节码指令。其中monitorenter指令是占用操作数栈顶引用对象,monitorexit指令是解除占用。如果修饰方法时,方法在编译成字节码时会被标记为ACC_SYNCHRONIZED,其实就是相当于在方法全部代码的前后分别增加moniterenter和moniterexit。
    官方对monitorenter和monitorexit的解释如下:

    monitorenter
    每个对象都与一个monitor关联。当前仅当一个monitor被一个所有者所拥有时,这个monitor就被锁定了。线程执行monitorenter字节码时就是在尝试获取当前操作数栈顶引用的对象锁对应的monitor的所有权。分为如下几种情况:

    • 如果monitor的拥有者是0个,则当前执行线程获得了monitor的所有权,并将拥有者计数器值设为1。
    • 如果当前线程已经是该monitor的拥有者,则将拥有者计数器加一,当前线程继续执行代码,无需阻塞。
    • 如果该monitor被其他线程所拥有,则当前线程阻塞,直到monitor的拥有者计数器为0时才可获取到该monitor的所有权并开始执行后续代码。

    monitorexit的解释跟monitorenter正好是相反的。
    下面我们来看一下一段synchronized代码的字节码到底是什么样的:
    代码如下:

    public class Test{
    
        public void sayHello(){
    
            Object object = new Object();
    
            synchronized (object){
                System.out.println("hello");
            }
        }
    }
    

    字节码如下:

    public void sayHello();
        descriptor: ()V
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=4, args_size=1
             0: new           #2                  // class java/lang/Object
             3: dup
             4: invokespecial #1                  // Method java/lang/Object."<init>":()V
             7: astore_1
             8: aload_1
             9: dup
            10: astore_2
            11: monitorenter
            12: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
            15: ldc           #4                  // String hello
            17: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            20: aload_2
            21: monitorexit
            22: goto          30
            25: astore_3
            26: aload_2
            27: monitorexit
            28: aload_3
            29: athrow
            30: return
    

    可以看到偏移量为11和21的两行代码正是我们刚说过的。偏移量0-10所做的事情是new 了一个Object对象并初始化,将其引用放在了操作数栈顶。11其实就是在请求这个object的monitor的所有权。

    相关文章

      网友评论

          本文标题:synchronized实现原理

          本文链接:https://www.haomeiwen.com/subject/icvyahtx.html