标签:无锁 synchronized 对象 介绍 获取 线程 轻量级 偏向
本文主要介绍synchronized的锁实现。
锁的存储
Java中的每一个对象都可以作为锁。synchronized关键字分为如下三种场景:
- 修饰普通方法时,锁住的是调用该方法的对象实例
- 修饰静态方法时,锁住的死当前类的Class对象
- 修饰代码块时,锁住的是括号里的配置的对象
Java对象头内部有一个Mark Word,存储着对象的hashcode、分代年龄、持有偏向锁的线程ID,锁标志位等信息。锁信息就存储在对象头。
锁的分类
锁按照级别从低到高依次是: 无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁。锁可以升级但不能降级。
几种锁对应的
锁类型 | 最多参与竞争的线程个数 | 最多线程竞争时各个线程状态 |
---|---|---|
偏向锁 | 1个 | 获取锁 |
轻量级锁 | 2个 | 1个已经获取锁, 一个自旋等待 |
重量级锁 | 大于等于3 | 1个已经获取锁, 其他的阻塞等待 |
无锁
无锁没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。
一般使用CAS来实现。无锁在某些场景下的性能很高。
偏向锁
大部分情况下,锁不仅不存在竞争,而且是由同一个线程多次获取该锁。从而引入了偏向锁的概念。
偏向锁是指当一段同步代码一直被一个线程所访问,那么该线程会自动获取锁,从而降低获取锁的代价。
偏向锁的获取:
- 当一个线程获取锁时, 会在对象头内部记录该线程的ID
- 当该线程退出或者重新获取锁时, 不需要使用CAS进行操作, 只需要简单判断对象头内部是否存储着该线程的ID, 若存在, 则获取锁成功。
偏向锁的释放:
偏向锁并不会自己主动撤销, 只有当有其他线程来竞争锁, 持有偏向锁的线程才会释放偏向锁,撤销之后, 将会恢复到无锁或者轻量级锁状态。
轻量级锁
当锁是偏向锁的时候,且被另外的线程所访问,此时偏向锁就会升级为轻量级锁,其他线程会通过自旋的形式尝试获取锁,不会阻塞,从而提高性能。
重量级锁
在轻量级锁的状态下,若当前只有一个等待线程,则该线程通过自旋等待。但是出现以下两种情况时,轻量级锁就会升级成重量级锁,此时等待锁的线程进入都会进入阻塞状态。
- 自旋等待线程的自旋次数超过最大值。
- 此时出现第三个线程来竞争锁。
参考资料:
- https://tech.meituan.com/2018/11/15/java-lock.html
- 《并发编程的艺术》
标签:无锁,synchronized,对象,介绍,获取,线程,轻量级,偏向 来源: https://blog.csdn.net/huangsky001/article/details/115282072
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。