java无锁,偏向锁,轻量级锁,重量级锁

78 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

背景

  • 纤程(协程),线程

  • 锁状态概念理解

  • 锁升级过程理解

过程

  • 纤程(协程),线程 纤程和协程表示同一个概念。是处于用户态的线程且与内核态的线程数的比例是m:n。在用户态切换线程的时候,不需要操作系统的辅助。一般m是远大于n的。 线程,可以理解为用户态的线程与内核态数量是1:1的对应关系。当用户态的线程进行切换的时候,需要操作系统进行辅助。
  • 对象头基础知识 对象头中的markwork标识着对象的锁状态信息。 mark word 包含的内容 : 对象哈希码,对象分代年龄,指向记录的指针,指向重量级锁记录的指针,GC标记,偏向线程ID,偏向时间戳。 在这里插入图片描述
  • 锁的状态概念
  1. 无锁
  2. 偏向锁。一个线程拿到资源后,标记一下即可。是没有任何线程进行锁竞争的。
  3. 轻量级锁。线程之间对同一个资源的竞争程度不激烈,但是已经存在竞争关系了。
  4. 重量级锁。线程之间对同一个资源的竞争程度很激烈,存在大量的锁竞争关系
  • 锁升级过程理解 在这里插入图片描述
  1. 锁的升级过程,其实就是对使用的一个优化,根据具体的场景,变换锁的状态,提高性能。

  2. 当新new出一个对象的时候,o是处于一个无锁状态的。

  3. A线程来了。线程A把o这个资源的状态标记成偏向锁了,这个时候,A线程一直占用着资源。

  4. 此时,B线程来了,先把资源的标记给清除掉,让资源从偏向锁的状态,变成轻量级锁。然后,B线程进行自旋,直到拿到资源,执行逻辑。

  5. B线程在自旋的过程中,又来了很多线程,大家都自旋等着,如果都自旋的话,将会消耗很多cpu资源。如果把他们交给内核态进行管理,把这些线程进行一个阻塞队列的排队,这样就不会消耗太多cpu资源了。此时,进入重量级锁状态。

  6. 无锁,偏向锁,轻量级锁都是用户态级别的。重量级锁就是内核态级别的,就是交给操作系统进行管理,而它也是通过阻塞队列的方式,进行排队,然后拿到资源,执行逻辑。

  7. 由轻量级变换成重量级标准是什么?占用资源的时间长度;处于自旋中的线程数量。

小结

  1. 理解java中,加了锁与不加锁,对象头的markword的变化。

  2. 理解锁的升级过程。这些锁升级过程,都是jvm自己做的,无需开发者显示处理。