Java基础内容之synchronized锁升级

简介: 偏向锁顾名思义,它会偏向于第一个访问锁的线程,如果在运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下,就会给线程加一个偏向锁。说白了,没有竞争,还叫啥锁呀。就是加了一个标记。认为没有人给你竞争。

作者: 西魏陶渊明
博客: https://blog.springlearn.cn/

一、重量级锁

什么叫重量级锁?

就是申请资源必须经过kernel(内核也叫操作系统),调用。

二、轻量级锁

轻量级锁,是不经过操作系统。轻量级锁是相对于重量级锁来叫的,也可以叫乐观锁。

在Java中乐观锁就是cas操作(compare and swap)根据英文翻译就是比较和交换。
底层都是调用的Unsafe里面的方法,可以看到这些方法是native方法。

通过看jvm源码,看到c++的代码有一个汇编语言支持cas

但是,这条cmpchg1不具有原子性,点进lock_if_mp(%4)里

最终实现是lock cmpxchg 指令:表示在硬件在执行后面的指令会锁定一个北桥总线。(相当于锁定总线,但是比锁总线要轻量级)解决了下面的问题

三、偏向锁

顾名思义,它会偏向于第一个访问锁的线程,如果在运行过程中,同步锁只有一个线程访问,不存在多线程争用的情况,则线程是不需要触发同步的,这种情况下,就会给线程加一个偏向锁。
说白了,没有竞争,还叫啥锁呀。就是加了一个标记。认为没有人给你竞争。

四、锁升级步骤

偏向锁 -> 轻量级锁 -> 重量级锁

在jdk1.6之前synchronized直接就是一个重量级锁,一了百了。
jdk优化后出现了,锁升级的概念。

那么其实synchronized的执行过程:

  1. 检测Mark Word里面是不是当前线程的ID,如果是,表示当前线程处于偏向锁
  2. 如果不是,则使用CAS将当前线程的ID替换Mard Word,如果成功则表示当前线程获得偏向锁,置偏向标志位1(前面一个线程刚好释放的情况下,这个才能成功,否则看3)
  3. 如果失败,则说明发生竞争,撤销偏向锁,进而升级为轻量级锁。
  4. 当前线程使用CAS将对象头的Mark Word替换为锁记录指针,如果成功,当前线程获得锁
  5. 如果失败,表示其他线程竞争锁,当前线程便尝试使用自旋来获取锁。
  6. 如果自旋成功则依然处于轻量级状态。
  7. 如果自旋失败,则升级为重量级锁。

翻译成白话问:

  1. 当没有人跟你竞争就是一个偏向锁,当cas失败了,说明有人跟你竞争了,这个时候锁就从偏向锁升级成了轻量级锁。
  2. 轻量级锁的状态下,仍然还有很多线程来竞争,那么此时cas就会比较严重从而浪费cpu执行。就升级为重量级锁。

其次其他等待线程就进入了阻塞状态。

最后求关注,求订阅,谢谢你的阅读!

相关文章
|
23天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
23天前
|
安全 Java 编译器
深入理解Java中synchronized三种使用方式:助您写出线程安全的代码
`synchronized` 是 Java 中的关键字,用于实现线程同步,确保多个线程互斥访问共享资源。它通过内置的监视器锁机制,防止多个线程同时执行被 `synchronized` 修饰的方法或代码块。`synchronized` 可以修饰非静态方法、静态方法和代码块,分别锁定实例对象、类对象或指定的对象。其底层原理基于 JVM 的指令和对象的监视器,JDK 1.6 后引入了偏向锁、轻量级锁等优化措施,提高了性能。
46 3
|
2月前
|
缓存 Java
java中的公平锁、非公平锁、可重入锁、递归锁、自旋锁、独占锁和共享锁
本文介绍了几种常见的锁机制,包括公平锁与非公平锁、可重入锁与不可重入锁、自旋锁以及读写锁和互斥锁。公平锁按申请顺序分配锁,而非公平锁允许插队。可重入锁允许线程多次获取同一锁,避免死锁。自旋锁通过循环尝试获取锁,减少上下文切换开销。读写锁区分读锁和写锁,提高并发性能。文章还提供了相关代码示例,帮助理解这些锁的实现和使用场景。
java中的公平锁、非公平锁、可重入锁、递归锁、自旋锁、独占锁和共享锁
|
2月前
|
Java 开发者
Java 中的锁是什么意思,有哪些分类?
在Java多线程编程中,锁用于控制多个线程对共享资源的访问,确保数据一致性和正确性。本文探讨锁的概念、作用及分类,包括乐观锁与悲观锁、自旋锁与适应性自旋锁、公平锁与非公平锁、可重入锁和读写锁,同时提供使用锁时的注意事项,帮助开发者提高程序性能和稳定性。
114 3
|
2月前
|
Java 开发者
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
在Java多线程编程的世界里,Lock接口正逐渐成为高手们的首选,取代了传统的synchronized关键字
52 4
|
2月前
|
SQL Java OLAP
java实现“数据平滑升级”
java实现“数据平滑升级”
48 2
|
3月前
|
Java
Java 中锁的主要类型
【10月更文挑战第10天】
|
2月前
|
SQL Java OLAP
java实现“数据平滑升级”
java实现“数据平滑升级”
25 0
|
缓存 Java 编译器
从Java 8升级到Java 11的注意事项
虽然Java最新版本已经发展到Java 18了,但市面上大部分的项目还在使用Java 8。由于从Java 8之后,Java API不一定向前兼容,因此很多人都对升级Java版本心存顾虑。Java 11是Java 8的下一个长期支持版本,毫无疑问Java 11比Java 8更加优秀。
2192 0
|
11天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
56 17