三、深入理解synchronized分析

1.了解java对象的存储结构

  1. 在学习synchronized 之前我们需要先了解一下 java对象包含了什么?如下图所示:
    在这里插入图片描述
  • 对象头
    • mark word:主要用来标识对象的线程锁状态,另外可以配合GC、存放该对象的hashcode
    • klass word:记录用于标识对象指向方法区中class信息的指针
    • 数组长度:只有当对象是数组的时候才会有这部分
  • 对象体
    • 对象体是用于保存对象属性和值的部分
  • 对齐字节
    • 对齐跟数据在内存中的位置有关,需要字节对齐的根本原因在于CPU访问数据的效率问

2.锁的状态

  1. 刚刚我们已经了解到了mark word存储了线程锁的状态,接下来让我们看看Mark word在64位操作系统的表现形式,如下图所示:

在这里插入图片描述

  • 偏向锁位(biased_lock)占有一个进制位,0表示对象没有偏向锁,1表示对象获取了偏向锁
  • 锁标志位(lock)占有两个进制位,和biased_lock共同表示表示锁的状态

3.锁升级过程

  • 锁升级过程:new -> 偏向锁 ->轻量级锁(无锁,自旋锁,自适应自旋) ->重量级锁 ,如下图所示:

在这里插入图片描述

  1. 当new object()的时候,没有任何线程来竞争,是无锁状态(锁=0 0 1)
  2. 当有一个线程来竞争时,先使用偏向锁,表示锁对象偏爱这个线程,线程在调用锁的这块代码,无需检查和切换,效率非常高
  3. 当两个线程开始竞争同一个锁,会先撤销偏向锁升级为轻量级锁。线程在自己的线程栈生成LockRecod,用CAS操作将markword设置为指向自己这个线程的LR的指针,设置成功者得到锁
  4. 当多个线程竞争同一个锁,导致更多wait,锁会升级为重量级锁。这个锁对象Mark Word再次发生变化,会指向一个监视器对象,这个监视器对象用集合的形式,来登记和管理排队的线程

4.synchronized是可重入锁

  • 重入锁:重入次数必须记录,因为和解锁次数必须对应
  • 因为继承,父类方法被sychronized修饰,子类在方法中调用super.该方法,所以可以使用父类的锁,所以是可重入的

5.锁消除(lock eliminate)和 锁粗化(lock coarsening)

  1. 锁消除

    /**
     * This method synchronizes on {@code this}, the destination
     * object, but does not synchronize on the source ({@code sb}).
     *
     * @param   sb   the {@code StringBuffer} to append.
     * @return  a reference to this object.
     * @since 1.4
     */
    public synchronized StringBuffer append(StringBuffer sb) {
        toStringCache = null;
        super.append(sb);
        return this;
    }
  • StringBuffer是线程安全的,是因为 append 方法被synchronized 修饰过,参考上述源码注释,我们可以看出源码写的是:synchronized只用于 append这个方法,不作用在sb这个引用上。 因此sb是不共享的资源,JVM会自动消除Stringbuffer 对象内部的锁
  1. 锁粗化
StringBuffer sb=new StringBuffer();  
while(i < 50){
     sb.append(str);
  }
  • JVM 会检测到这样一连串的操作都对同一个对象加锁(while 循环内 50次执行 append,没有锁粗化的就要进行 50次加锁/解锁),此时 JVM 就会将加锁的范围粗化到这一连串的操作的外部(比如 while 虚幻体外),使得这一连串操作只需要加一次锁即可。

6.为什么有自旋锁还需要重量级锁?

  • 自旋锁是为了减少线程的阻塞,但是会占用cpu的资源,如果持有锁的线程需要执行的同步代码块时间很长,就会浪费大量的cpu资源

7.偏向锁是否一定比自旋锁效率高?

  • 不一定,在知道有多线程竞争的情况下,偏向锁会涉及大量的锁撤销,效率低,这个时候使用自旋锁会更好一些

参考文档:
java对象结构与锁实现原理及MarkWord详解

欢迎大家关注我的微信公众号共同学习进步:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值