专业的JAVA编程教程与资源

网站首页 > java教程 正文

Java内置锁:synchronized

temp10 2025-05-15 20:57:58 java教程 2 ℃ 0 评论

synchronized

在 Java 中,synchronized 是实现线程同步的核心机制,其底层原理涉及 对象头结构、Monitor 锁模型 和 锁升级优化。

一、synchronized 的作用

  • 原子性:确保同一时刻只有一个线程执行同步代码。
  • 可见性:线程解锁前,变量修改会强制刷入主内存;加锁时,从主内存重新加载变量。
  • 有序性:通过锁限制指令重排序(遵守 as-if-serial 和 happens-before 规则)。

二、底层实现:对象头与 Monitor

  1. 对象头结构

每个 Java 对象在堆中存储时,对象头包含 Mark Word(存储锁状态)和 类型指针。

Java内置锁:synchronized

锁状态通过 biased_lock 和 lock 标志位标识。

2. Monitor 机制

每个对象关联一个 Monitor(由 C++ 实现的 ObjectMonitor 结构)。

Monitor 关键字段:

_owner:持有锁的线程。_EntryList:竞争锁时阻塞的线程队列。_WaitSet:调用 wait() 后进入等待状态的线程队列。

加锁过程:

线程尝试通过 CAS 操作将 Mark Word 替换为指向 Monitor 的指针。成功则获得锁;失败则进入 _EntryList 阻塞等待。

三、锁升级优化(JDK 6+)

为提高性能,JVM 会根据竞争情况动态升级锁状态:

  1. 偏向锁(Biased Lock)

适用场景:没有实际竞争,仅单个线程反复获取锁。实现:在 Mark Word 中记录线程 ID,后续同一线程无需 CAS 操作。

示例:

Object lock = new Object();
synchronized (lock) { 
    // 首次进入:升级为偏向锁 
    // 同步代码
}
  1. 轻量级锁(Lightweight Lock)

适用场景:锁竞争轻微,多线程交替执行。实现:通过 自旋(CAS) 尝试获取锁,避免线程阻塞。

synchronized (lock) { 
    // 存在竞争但短暂:升级为轻量级锁 
    for (int i = 0; i < 100; i++)
    { 
        // 低竞争循环操作 
    }
}
  1. 重量级锁(Heavyweight Lock)

适用场景:高并发竞争,自旋消耗 CPU 资源。

实现:锁升级为重量级锁,未获取锁的线程进入阻塞状态(依赖操作系统互斥量)。

synchronized (lock) 
{ 
    // 高竞争场景:升级为重量级锁 
   // 高并发操作(如数据库连接池竞争)
}

四、性能优化机制

自适应自旋

JVM 根据历史自旋成功率动态调整自旋次数。

锁消除(Lock Elimination)

编译器通过逃逸分析,去除不可能存在竞争的锁(如局部变量同步)。

public void method() 
{ 
    Object localObj = new Object(); 
    synchronized (localObj) 
    { 
        // 锁被消除 
        // 局部对象无并发访问
     }
}

锁粗化(Lock Coarsening)

将相邻的同步块合并,减少锁的获取/释放次数。

synchronized (lock) 
{ 
    // 操作1
}
synchronized (lock) 
{ 
    // 合并为一个同步块 
    // 操作2
}

五、与 ReentrantLock 对比

特性

synchronized

ReentrantLock

实现方式

JVM 内置实现

基于 AQS 的 API 实现

锁获取方式

自动加锁/解锁

需手动 lock() 和 unlock()

灵活性

有限(非公平锁为主)

支持公平锁与非公平锁

条件变量

通过 wait()/notify() 实现

通过 Condition 实现多个条件

锁升级优化

支持(偏向锁→轻量级→重量级)

无锁升级,始终基于 AQS 竞争

六、总结

  • 底层核心:通过对象头标记锁状态,依赖 Monitor 控制线程竞争。
  • 锁升级:根据竞争激烈程度动态优化(偏向锁→轻量级→重量级)。
  • 优化手段:自旋、锁消除、锁粗化降低同步开销。
  • 适用场景:轻量级同步推荐 synchronized,复杂需求(如超时、公平性)使用 ReentrantLock。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表