java里面Synchronized关键字的底层原理

###  Monitor对象

Monitor 对于每一个java对象都关联一个Monitor对象,如果使用synchronized关键,给对象上锁(重量级锁)之后,该对象的Mark word中就会设置指向Monitor对象的指针。下图是32位jvm的mark word 组成:

上图是Monitor的结构:

刚开始Monitor对象中的owner为null, 当线程Thread-2执行synchronized(obj)的时候,就会将monitor的owner置为Thread-2, 而且Monitor对象的owner只能有一个,所以当其他线程,在执行synchornized(obj)时,Thread-3,Thread-4,Thread-4 就会就如EntryList的队列里面。

当Thread-2的代码执行完毕,释放锁对象,同时唤醒EntryList中的Thread来竞争锁,而且是非公平的竞争。

### 轻量级锁:

    所谓轻量级锁,就是多个线程在访问同一个锁对象的时候 是时间错开的,没有竞争的状态。还是使用synchronized

 static  Object object = new Object();
    public static void method1() {
        synchronized (object) {
            //同步块A
            method2();
        }
    }

    private static void method2() {
        synchronized (object) {
            //同步块B
        }
    }

当Thread-1在执行上面的代码的时候,会在线程栈中的method1栈帧中创建Lock Record(锁记录对象) ,并且让Lock Record的Object Reference执行Object锁对象,并尝试用CAS替换Object的mark word, 将mark word的值放到Lock Record里面。如下图所示:

如果CAS失败,就会有下面两种情况:

  1. 如果其他线程已经持有了Object对象的轻量级锁,那么对于当前线程来说,就是有竞争则要进入到锁膨胀过程。

   2. 如果是当前自己的线程,则要执行synchronized锁重入,那么需要在当前线程的栈中在添加一条Lock Record记录。将Lock Record 中的Object Reference指向锁对象,话有Lock Reference第一个位置置为null. 过程如下图:

   

### 解锁的过程

  在退出synchronized代码块(解锁)的时候,先判断Lock Record 里面的数据有为null,表示有重入,这是重置锁的记录,也就是把栈里面的Lock Record为null 的数据删除,直到剩下不为null的Lock Record的记录。开始还原object的Mark word操作。

利用CAS将Lock record 里面的数据(之前交换的数据)还原到Object里面的mark word中,结果成功则完成解锁,失败表示已经进入了锁膨胀,需要重量级锁的解锁过程。

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值