Java锁机制、锁升级
Java锁机制从公平性来说可以分为公平锁和非公平锁,
从可重入来说可以分为可重入锁和非可重入锁,
还可以分为独占锁和共享锁,乐观锁和悲观锁,
自旋锁、偏向锁、轻量级锁、重量级锁
锁升级:
偏向锁、轻量级锁、重量级锁
偏向锁会偏向于第一个获取它的线程,如果在接下来的执行过程中,该锁一直没有被其他线程获取,则持有该偏向锁的线程将永远
不需要再进行同步。
当锁对象第一次被线程获取的时候,虚拟机将会把对象头中的偏向模式设置为“1”,表示进入偏向模式。
同时使用cas操作把获得这个锁的线程id记录在对象的markword之中,如果CAS操作成功,持有偏向锁的线程以后每次进入这个锁相关的同步块时,虚拟机都可以不再进行任何同步操作。
轻量级锁
“轻量”是相对于使用操作系统互斥量来实现的传统锁而言的,因此传统的锁机制被称为重量级锁。
轻量级锁设计的初衷是在没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。
轻量级锁的工作过程:在代码即将进入同步块的时候,如果此同步对象没有被锁定,虚拟机首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝。然后,虚拟机将使用CAS操作尝试把对象的Mark Word更新为指向Lock Record的指针。如果这个更新动作成功了,即代表该线程拥有了这个对象的锁,表示此对象处于轻量级锁定状态。如果这个更新操作失败了,那就意味着至少存在一条线程与当前线程竞争获取该对象的锁。
轻量级锁能提升程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这一经验法则。
如果没有竞争,轻量级锁便通过CAS操作成功避免了使用互斥量的开销;但如果确实存在锁竞争,除了互斥量的本身开销外,还额外发生了CAS操作的开销,因此在有竞争的情况下,轻量级锁反而会比传统的重量级锁更慢。