详细讨论Java中偏向锁、轻量级锁及重量级锁实现原理

最近因为工作关系遇到了很多Java并发编程的问题,然后恶补了一下,现在就来说说Java目前的锁实现原理

其实在JDK1.5以前的早期版本,还没有那么细粒度完善的锁机制,基本上就一个synchronized打遍天下,但是从JDK1.6之后Oracle对Java锁进行了很大的改动,也就出现了偏向锁/轻量级锁机制和锁的升级/降级机制

偏向锁和轻量级锁都属于乐观锁,偏向锁指的是没有其他线程竞争资源,只有一个线程在执行同步块代码,这个时候在会使用CAS操作在对象头部信息中写进拿到锁的那个线程ID/锁级别等信息,偏向锁的使用场景主要是为了提高执行性能,因为在大多数情况下并不存在频繁的多个线程对于同一个代码块进行竞争,那么就没必要同一个线程执行还执行拿锁/释放锁这种耗时操作,大致流程下图:

详细讨论Java中偏向锁、轻量级锁及重量级锁实现原理_第1张图片

而当第一个拿到偏向锁的线程执行时,遇到有新的进程在询问统一代码块的锁时就有可能会升级成轻量级锁,为什么说是有可能呢?因为偏向锁不会自动释放,此时第2个线程询问锁时会出现2种情况:

  1. 第一个线程已经执行完毕,那么CAS操作将Mark Word设置为Null,第二个线程获取偏向锁,此时不会升级成轻量级锁
  2. 第一个线程未执行完毕,此时第二个线程获取锁失败,那么会进行自旋,当自旋达到一定次数后,就会升级成轻量级锁

轻量级锁流程见下图:

详细讨论Java中偏向锁、轻量级锁及重量级锁实现原理_第2张图片

同理,当需要获取锁的线程越来越多并且自旋达到一定数目后,就会升级成重量级锁,重量级锁也就是悲观锁,完全阻塞状态,必须等待线程执行完成释放锁之后排队线程才能挨个执行,这个就是锁的升级过程

那么锁什么时候发生降级呢?其实简单理解说就是当竞争线程变少或者无竞争时,就会从重量级锁开始降级

 

你可能感兴趣的:(Java,编程技术)