美文网首页
Java的Synchronzied关键字

Java的Synchronzied关键字

作者: 一剑光寒十九洲 | 来源:发表于2018-07-08 23:35 被阅读0次

    写作时间:2018.07.08
    最后更新时间:2018.07.08

    public class Sync {
    
        private static Object lock = new Object();
    
        public static void main(String[] args) {
            int i = 0;
            while (i++ < 100000) {
                doSomething();
            }
        }
        
        public static void doSomething() {
            int a = 0;
            synchronized (lock) {
                a++;
            }
        }
    }
    

    使用参数-XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly编译运行之后,可以看到如下信息:

      0x00007f6cbcce3385: jne     0x7f6cbcce33e4    ;*monitorenter
                                                    ; - Sync::doSomething@7 (line 14)
    
      0x00007f6cbcce338b: lea     0x20(%rsp),%rax
      0x00007f6cbcce3390: mov     0x8(%rax),%rdi
      0x00007f6cbcce3394: mov     (%rdi),%rsi
      0x00007f6cbcce3397: and     $0x7,%rsi
      0x00007f6cbcce339b: cmp     $0x5,%rsi
      0x00007f6cbcce339f: je      0x7f6cbcce33bc
      0x00007f6cbcce33a5: mov     (%rax),%rsi
      0x00007f6cbcce33a8: test    %rsi,%rsi
      0x00007f6cbcce33ab: je      0x7f6cbcce33bc
      0x00007f6cbcce33b1: lock cmpxchg %rsi,(%rdi)
      0x00007f6cbcce33b6: jne     0x7f6cbcce33f4    ;*monitorexit
                                                    ; - Sync::doSomething@12 (line 16)
    

    可见,在Java中,synchronzied关键字是使用字节码monitorenter和moniterexit来实现的。monitorenter指令是在编译后插入到同步代码块的开始位置,而monitorexit是插入到方法结束处和异常处, JVM要保证每个monitorenter必须有对应的monitorexit与之配对。任何对象都有一个 monitor 与之关联,当且一个monitor 被持有后,它将处于锁定状态。线程执行到 monitorenter 指令时,将会尝试获取对象所对应的 monitor 的所有权,即尝试获得对象的锁。
    那么这个所谓的锁在哪呢?
    在Hotspot中,对象在内存中存储的布局可以分为3块:对象头,实例数据和为了对齐而做的填充。
    对象的锁就保存在对象头的第一个字Mark Word中,在一个64位的虚拟机中,Mark Word就是64位长的,其中有3位和锁有关系,1位表示是否是偏向锁,2位表示锁状态,共有无锁定,轻量级锁定,重量级锁定3种状态。monitorenter和monitorexit就是通过操纵这3位来实现的。

    相关文章

      网友评论

          本文标题:Java的Synchronzied关键字

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