网站首页 > java教程 正文
JDK1.6为了减少获得锁和释放锁所带来的性能消耗,引入了“偏向锁”和“轻量级锁”,所以在JDK1.6里锁一共有四种状态,无锁状态,偏向锁状态,轻量级锁状态和重量级锁状态,它会随着竞争情况逐渐升级。锁可以升级但不能降级,意味着偏向锁升级成轻量级锁后不能降级成偏向锁。这种锁升级却不能降级的策略,目的是为了提高获得锁和释放锁的效率.
- Java 中锁有几种状态:无锁 → 偏向锁 → 轻量级锁 → 重量级锁
在 JDK 15 的版本上面,移除了偏向锁了
无锁状态
程序不会有锁的竞争。第一个线程执行完之后,第二个线程再去执行。
偏向锁
偏向锁,字面理解就是说会偏向于第一个访问锁的线程
- 当一个线程访问一个同步代码块时,首先会尝试获取偏向锁。
- 如果该对象没有被其他线程锁定,并且没有发生过竞争,那么当前线程会将对象头中的标记设置为偏向锁,并将线程ID记录在对象头中。
- 当其他线程尝试获取该对象的锁时,会检查对象头中的标记,如果是偏向锁并且线程ID与当前线程ID相同,表示可以获取锁,无需进行同步操作。
- 如果其他线程尝试获取该对象的锁时,发现对象头中的标记不是偏向锁或者线程ID不匹配,表示发生了竞争,偏向锁会升级为轻量级锁。
偏向锁的优势
在于减少了同步操作的开销,适用于大部分情况下只有一个线程访问同步代码块的场景。但是如果存在多个线程竞争同一个锁的情况,偏向锁会失效,需要升级为轻量级锁或重量级锁。
一个对象刚开始实例化的时候,没有任何线程来访问它的时候。它是可偏向的,意味着,它现在认为只可能有一个线程来访问它,所以当第一个线程来访问它的时候,它会偏向这个线程,此时,对象持有偏向锁。偏向第一个线程,这个线程在修改对象头成为偏向锁的时候使用CAS操作,并将对象头中的ThreadID改成自己的ID,之后再次访问这个对象时,只需要对比ID,不需要再使用CAS在进行操作。
一旦有第二个线程访问这个对象,因为偏向锁不会主动释放,所以第二个线程可以看到对象时偏向状态,这时表明在这个对象上已经存在竞争了,检查原来持有该对象锁的线程是否依然存活,如果挂了,则可以将对象变为无锁状态,然后重新偏向新的线程,如果原来的线程依然存活,则马上执行那个线程的操作栈,检查该对象的使用情况,如果仍然需要持有偏向锁,则偏向锁升级为轻量级锁,(偏向锁就是这个时候升级为轻量级锁的)。如果不存在使用了,则可以将对象回复成无锁状态,然后重新偏向。
轻量级锁
轻量级锁是在 JVM 环境上面
轻量级锁在以下情况下会升级为重量级锁:
- 当多个线程竞争同一个锁时,如果自旋等待超过了一定的次数,轻量级锁会升级为重量级锁。
- 当一个线程已经持有锁,另一个线程在自旋等待获取锁,而此时又有第三个线程试图访问该锁时,轻量级锁也会升级为重量级锁。
这种升级过程是为了处理更复杂的并发情况,确保线程安全,但也会带来一定的性能开销。因此,在设计并发系统时,需要仔细考虑锁的使用和升级策略,以平衡性能和线程安全的需求。
重量级锁
重量级锁是在操作系统环境上面。重量级锁会阻塞线程。
重量级锁是指当一个线程获取锁之后,其余所有等待获取该锁的线程都会处于阻塞状态。它是依赖于底层操作系统的Mutex实现,也就是互斥锁。重量级锁会让锁从用户态切换到内核态,将线程的调度交给操作系统,因此性能相对较低。
在并发编程中,当锁的状态为轻量级锁时,若有另一个线程尝试获取锁但自旋一定次数后仍未成功,那么该锁就会升级为重量级锁,此时其他申请锁的线程会进入阻塞状态,导致性能下降。
总的来说,重量级锁是为了确保线程安全而采取的一种机制,但使用时应注意其带来的性能开销,并尽量通过合理的锁策略来避免不必要的阻塞和性能损失。
猜你喜欢
- 2024-12-31 GitHub Copilot最新升级!61%的Java开发者用来摸鱼,效率提升55%
- 2024-12-31 Java批量更新太慢?多线程+List分段完美解决
- 2024-12-31 如何使用Puppet开源配置管理工具更新Java项目?
- 2024-12-31 Java 热更新 Groovy 实践及踩坑指南
- 2024-12-31 什么?Java都更新到19了?Java 19新特性详解!
- 2024-12-31 干货!微服务全量升级JDK17,踩坑笔记整理
- 2024-12-31 最简单的K8S入门(四)扩缩容&滚动更新
- 2024-12-31 java 8项目升级JDK11升级改造步骤
- 2024-12-31 Java 近期更新:OpenJDK JDK Jakarta EE Spring等
- 2024-12-31 nacos配置更新后,java项目无需重启配置就生效
你 发表评论:
欢迎- 04-24Java Collections 工具类集合框架中常用算法解析
- 04-24桶排序的简单理解
- 04-24Java集合框架底层实现原理大揭秘
- 04-24Java 集合框架全面解析:选对数据结构,提升开发效率
- 04-24c#集合排序
- 04-24Java面试中常被问到的集合类深度解读
- 04-24VBA技术资料MF278:对集合进行排序
- 04-24Spring 最常用的 7 大类注解,史上最强整理
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)