锁的基本概念与实现

锁与对象头

锁的作用:
保护临界区资源不会被多个线程同时访问而受到破坏。通过锁,可以让多个线程排队,一个一个地进入临界区访问目标对象, 使目标对象的状态总是保持一致。

对象内存分布:
对象在内存中存储的布局可以分为3块区域:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。

对象头:
对象头(Object Header)包括两部分信息:
第一部分用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID等等,这部分数据的长度在32位和64位的虚拟机中分别为32个和64个Bits,官方称它为“Mark Word”。
Mark Word被设计成一个非固定的数据结构以便在极小的空间内存储尽量多的信息,它会根据对象的状态复用自己的存储空间。
这里写图片描述
对象头的另外一部分是类型指针,即是对象指向它的类的元数据的指针,虚拟机通过这个指针来确定这个对象是哪个类的实例。

实例数据:
实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容。无论是从父类中继承下来的,还是在子类中定义的,都需要记录下来。

对齐填充:
HotSpot虚拟机要求对象的起始地址必须是8字节的整数倍,也就是对象的大小必须是8字节的整数倍。而对象头部分正好是8字节的倍数(1倍或者2倍),因此,当对象实例数据部分没有对齐的时候,就需要通过对齐填充来补全。

锁的的作用:
概述:
在多线程程序中,线程之间的竞争是不可避免的,而且是一种常态,如何使用更高的效率处理多线程的竞争,是Java 虚拟机一项重要的使命。如果将所有的线程竞争都交由操作系统处理,那么并发性能将是非常低下的,为此,虚拟机在操作系统层面挂起线程之前,会先尽一切可能在虚拟机层面上解决竞争关系,尽可能避免真实的竞争发生。同时,在竞争不激烈的场合,也会试图消除不必要的竞争。

常见的锁:
锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态,这几个状态会随着竞争情况逐渐升级。锁可以升级但不能降级。

偏向锁:
偏向锁偏向于第一个获取它的线程,这个线程之后获取偏向锁后,就不需要再进行同步了。但是一旦有其他线程竞争这个锁,偏向锁就会则退出偏向模式膨胀为轻量级锁或重量锁。当一个线程访问同步块并获取锁时,会在对象头和栈帧中的锁记录里存储锁偏向的线程ID,以后该线程在进入和退出同步块时不需要进行CAS操作来加锁和解锁,只需简单地测试一下对象头的Mark Word里是否存储着指向当前线程的偏向锁。
使用-XX:+UseBiasedLocking 可以设置启用偏向锁,-XX:BiasedLockingStartupDelay设置开启偏向锁的延迟时间,默认4秒。
偏向锁在锁竞争激烈的场合没有太强的优化效果,因为大量的竞争会导致持有锁的线程不停地切换,锁也很难一直保持在偏向模式,此时,使用锁偏向不仅得不到性能的优化,反而有可能降低系统性能。
轻量级锁:
所谓轻量级锁,就是jvm认为,对于绝大部分的锁,在整个同步周期内都是不存在竞争的。也就是说如果一线程获取了锁,其他线程再去获取这个锁的概率比较低。不使用互斥量这样的重量级锁,而使用CAS操作去设置。但是如果另一个线程同样使用CAS去获取这个锁,轻量级锁就会膨胀为重量级锁。
轻量级锁使用CAS加锁的过程如下:
1、代码进入同步块,在栈帧中创建锁记录(Lock record),存储对象头的拷贝。
2、虚拟机CAS修改对象头指向锁记录的指针,指向栈帧中的锁记录地址。
3、如果CAS更新成功,则状态位改为00,表示地象处于轻量级锁的状态
4、如果CAS更新失败,虚拟机首先检查对象的对象头是否指向当前线程。是,则当前线程已经拥有这个对象锁,可以往下执行代码;否则,就是其他线程在争这个锁,那轻量级锁就会自旋一段时间后膨胀为重量级锁,标志位设置为10

轻量级锁解锁的过程也是用CAS操作的,如下:
1、把栈帧中的锁记录与对象头用CAS换回来,
2、替换成功,则同步周期完成
3、替换失败,则说明有其他线程在竞争这个锁,那轻量级锁就会膨胀为重量级锁,释放锁的时候要唤醒挂起的线程。

几种锁的对比:

这里写图片描述
详细参见
细说AQS
AQS

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值