温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Synchronized在JDK中的实现

发布时间:2025-07-03 10:07:08 来源:亿速云 阅读:97 作者:小樊 栏目:编程语言

synchronized 是 Java 中用于实现线程同步的关键字,它提供了互斥访问的机制,确保同一时刻只有一个线程可以执行特定的代码块或方法。synchronized 可以用于以下几种场景:

  1. 修饰实例方法:为当前对象实例加锁,进入同步方法需要先获取对象锁。
  2. 修饰静态方法:为当前类的 Class 对象加锁,锁定的是类对象。
  3. 修饰代码块:为指定对象加锁,可以指定对象,通常是实例对象或自定义对象。

synchronized 的底层实现依赖于 JVM 的监视器锁(Monitor)机制。每个 Java 对象都与一个监视器相关联,线程可以通过获取这个监视器来实现对对象的独占访问。以下是 synchronized 在 JDK 中的实现原理:

对象头与 Mark Word

在 JVM 中,每个对象由三部分组成:对象头(Header)、实例数据(Instance Data)和对齐填充(Padding)。对象头包含了两部分信息:

  • Mark Word:存储对象的哈希码、GC 分代年龄、锁状态等信息。
  • Klass Pointer:指向对象所属类的元数据的指针。

Mark Word 在不同锁状态下会存储不同的内容,例如无锁状态、偏向锁、轻量级锁和重量级锁。

锁的升级过程

Java 6 之后,synchronized 的锁状态会随着竞争情况从低到高逐步升级,这个过程是不可逆的:

  • 无锁状态:初始状态。
  • 偏向锁:适用于只有一个线程访问同步块的场景。
  • 轻量级锁:适用于多个线程交替访问同步块的场景。
  • 重量级锁:适用于多个线程同时竞争锁的场景。

监视器(Monitor)的工作机制

当锁升级到重量级锁时,JVM 会使用操作系统的互斥量(mutex)来实现同步,这时对象头中的 Mark Word 会指向一个监视器对象(Monitor)。监视器的主要结构包括:

  • Owner:持有锁的线程。
  • EntryList:等待获取锁的线程队列。
  • WaitSet:调用 wait() 方法后进入等待状态的线程队列。

锁的获取与释放

线程进入 synchronized 块时,尝试获取对象的 Monitor 锁。锁被持有后,其他线程无法进入被锁定的代码块。当线程退出同步块或方法时,锁会被释放,其他线程可以继续竞争锁。

JDK 中的优化措施

自 JDK 1.6 起,synchronized 进行了多项优化,以提高性能:

  • 锁膨胀/锁升级:从无锁状态到偏向锁,再到轻量级锁,最后到重量级锁的过程。
  • 锁消除:在某些情况下,JVM 会检测不到某段代码被共享和竞争的可能性,从而将这段代码所属的同步锁消除掉。
  • 锁粗化:将多个连续的加锁、解锁操作连接在一起,扩展成一个范围更大的锁。
  • 自适应自旋锁:线程自旋的次数不再是固定的值,而是一个动态改变的值,根据前一次自旋获取锁的状态来决定此次自旋的次数。

通过这些优化措施,synchronized 在不同的竞争场景中更加高效,同时保持了代码的简洁性和易用性。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI