深入JVM 高并发-锁

——自旋锁与自适应自旋 

互斥同步对性能最大的影响是阻塞的实现,挂起线程和恢复线程需要切换到内核态来完成,这些操作给系统的并发性能带来很大的压力。但是在许多应用上,共享数据的锁定状态只会持续一小段时间,为了这段时间去挂起和恢复线程不值得,如果物理机器有一个以上的处理器,能让2个或以上线程同时并行执行,就可以让后面请求锁的线程稍等一下,但不放弃处理器的执行时间,看持有锁的线程是否很快释放锁,为了让线程等待,只需让线程执行一个忙循环(自旋),即所谓的自旋锁

自旋锁从JDK1.4开始引入,不过默认是关闭的,在JDK1.6之后,默认是开启的。自旋等待不是阻塞,自选等待本身虽然可以避免线程切换的开销,但需要占用处理器的时间,那么自旋会白白消耗处理器资源,因此自旋等待的时间需要有一定的限度,且如果自旋超过一定次数仍然没有获得锁,则必须挂起等待,让出处理器,一般默认的次数是10次

JDK1.6引入的自适应自旋意味着自旋的时间不固定,由前一次在同一锁上自旋时间及锁的拥有者状态来决定

  • 如果在同一个锁对象上,自旋等待刚刚获得成功,并且持有锁的线程正在执行,那么虚拟机就认为这次自旋有可能成功,进而允许它自旋的时间更长
  • 而如果对于一个锁,自旋很少成功过,那么以后获取这个锁时将可能省略掉自旋过程,以避免处理器资源浪费

——锁消除

锁消除是指虚拟机即时编译器在运行时,对一些代码要求同步,但是被检测到不可能存在共享数据竞争的锁进行消除,锁消除的主要判定依据是来源于逃逸分析的数据支持,如果判断一段代码中,堆上的所有数据都不会逃逸被其他线程访问,那就可以把它们当作栈上的数据对待,认为是线程私有的,同步加锁就无需进行

——锁粗化

原则上,编写代码时,总是推荐同步的作用范围尽可能的小,只在共享数据的实际作用域中才进行同步,这样是为了使得需要同步的操作数量尽可能少,如果存在锁竞争,等待的线程也很快获得锁

但如果一系列的连续操作都对同一对象反复加锁和解锁,那即使没有线程竞争,频繁的进行互斥同步操作导致很大的性能开销

如 String.append()方法 虚拟机检测到一些的操作都是对同一个String 对象操作,那么会扩大锁的范围以提高性能

——轻量级锁

在JDK1.6之后引入新型锁机制,轻量级锁本意在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能开销,对象的内存布局,HotSpot虚拟机的对象头 Object Header分为2部分信息,第一部分用于存储对象本身运行时数据,如哈希码 Hashcode GC分代,称为 Mark Word 是实现轻量级锁和偏向锁的关键,对象的内存布局另一部分是存储指向方法区的对象类型数据的指针,当然如果对象是数组的话,还需要记录数组的长度

在32位HotSpot虚拟机对象未被锁定的情况下,MarkWord的32bit空间中25bit用于存储对象哈希码hashcode 4bit用于存储对象分代年龄,2bit用于存储锁定标志位,1bit固定为0 在其它状态下轻量级锁,重量级锁定,GC标记,可偏向存储内容如下


Mark Word 对象头的部分内容

存储内容 标志位 状态
对象hashcode 对象分代信息 01 未锁定状态
指向锁记录的指针 00 轻量级锁定
指向重量级锁指针 10 重量级锁定
11 GC标记
偏向线程ID 偏向时间戳 01 可偏向锁定

在代码进入同步块的时候,如果此时对象未被锁定(标志位01) 虚拟机首先在当前线程的栈帧建立一个锁记录 Lock Record的空间,用于存放对象目前的Mark Word拷贝(Displaced Mark Word)

虚拟机使用CAS操作 尝试将对象的Mark Word更新为指向Lock Record的指针,如果成功,说明,该线程成功获得了对象的锁,并且将Mark Word标志位设置为00 即表示对象处于轻量级锁定状态 

而如果更新失败,虚拟机首先检查对象的Mark Word是否指向当前栈帧,如果是,说明已经获取了该对象的锁,可以下一步执行,否则,说明该对象的锁被其它线程抢占了,那么轻量级锁设置为重量级锁 10   也就是等待锁的线程进入阻塞状态

轻量级锁基于这样一个常识:对于绝大部分锁,在整个同步期间不存在竞争,使用CAS减少互斥的开销。 

——偏向锁

JDK1.6之后引入一系列锁技术,目的消除数据在无竞争的情况下同步原语,进一步提高程序的性能,轻量级锁在无竞争的情况下使用CAS操作去消除同步使用的互斥量,那偏向锁在无竞争情况下消除同步过程

所谓偏,是指锁会偏向第一个获得它的线程,如果在接下来的执行过程中,该锁没有被其它线程获取,则持有偏向锁的线程永远不需要同步

偏向锁可以提高带有同步但无竞争的程序性能,但如果程序中的数据会经常被多线程访问,那偏向模式就会显得多余

猜你喜欢

转载自blog.csdn.net/qq_33369979/article/details/88637968