云计算百科
云计算领域专业知识百科平台

深入解析synchronized锁机制

好的,我们将分两课时详细讲解 synchronized 关键字。


第一课时:基础概念与使用

1. 什么是同步? 在多线程编程中,多个线程可能同时访问共享资源(如变量、对象),导致数据不一致或竞态条件。同步机制用于协调线程访问,确保共享资源在任意时刻只被一个线程操作。

2. synchronized 的作用

  • 原子性:确保操作不可分割。
  • 可见性:一个线程修改共享变量后,其他线程能立即看到最新值。
  • 有序性:禁止指令重排序(通过 as-if-serial 语义和 happens-before 规则)。

3. 使用方式 3.1 修饰实例方法

public synchronized void method() {
// 临界区代码
}

  • 锁对象是当前实例(this)。
  • 同一实例的多个线程调用此方法会互斥。

3.2 修饰静态方法

public static synchronized void staticMethod() {
// 临界区代码
}

  • 锁对象是类的 Class 对象(如 MyClass.class)。
  • 所有实例的线程调用此方法会互斥。

3.3 同步代码块

public void method() {
// 非同步代码
synchronized (lockObject) {
// 临界区代码
}
}

  • 显式指定锁对象(lockObject),可以是任意对象。
  • 灵活性高,可缩小同步范围提升性能。

4. 示例:计数器

public class Counter {
private int count = 0;

public synchronized void increment() {
count++; // 原子操作
}

public int getCount() {
return count;
}
}

http://my.tv.sohu.com/us/442657988/702996624.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjYyNC5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996731.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjczMS5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996629.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjYyOS5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996566.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU2Ni5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996736.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjczNi5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996834.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjgzNC5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996573.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU3My5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996576.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU3Ni5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996635.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjYzNS5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996736.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjczNi5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996834.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjgzNC5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996573.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU3My5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996576.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU3Ni5zaHRtbA==.html
http://my.tv.sohu.com/us/442657988/702996635.shtml
https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjYzNS5zaHRtbA==.html
 

  • 不加 synchronized 时,多线程并发 count++ 会导致结果错误。

第二课时:底层原理与锁优化

1. 对象头与锁标记 JVM 中每个对象包含对象头(存储 Mark Word),其中记录锁状态:

  • 无锁状态
  • 偏向锁
  • 轻量级锁
  • 重量级锁

2. 锁升级过程 2.1 偏向锁

  • 适用于单线程重复获取锁的场景。
  • 在 Mark Word 记录线程 ID,避免 CAS 操作。

2.2 轻量级锁

  • 当多线程竞争时,升级为轻量级锁。
  • 通过 CAS(Compare-And-Swap)尝试获取锁。
  • 若竞争失败,膨胀为重量级锁。

2.3 重量级锁

  • 通过操作系统 Mutex Lock 实现,线程阻塞并进入等待队列。
  • 涉及用户态到内核态的切换,开销较大。

3. 锁的存储结构

  • 锁对象:synchronized 作用的对象。
  • 锁记录(Lock Record):存储在栈帧中,用于保存锁的元数据。
  • 监视器(Monitor):JVM 为每个锁对象关联的同步机制,包含:
    • _owner:持有锁的线程。
    • _EntryList:等待获取锁的线程队列。
    • _WaitSet:调用 wait() 的线程队列。

4. 字节码层面

  • 同步代码块编译后,插入 monitorenter 和 monitorexit 指令:

    public void method();
    Code:
    0: aload_0
    1: dup
    2: astore_1
    3: monitorenter // 获取锁
    4: aload_1
    5: monitorexit // 释放锁
    6: goto 14
    9: astore_2
    10: aload_1
    11: monitorexit // 异常时释放锁
    12: aload_2
    13: athrow
    14: return

    http://my.tv.sohu.com/us/442657988/702996624.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjYyNC5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996731.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjczMS5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996629.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjYyOS5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996566.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU2Ni5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996736.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjczNi5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996834.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjgzNC5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996573.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU3My5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996576.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU3Ni5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996635.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjYzNS5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996736.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjczNi5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996834.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjgzNC5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996573.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU3My5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996576.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjU3Ni5zaHRtbA==.html
    http://my.tv.sohu.com/us/442657988/702996635.shtml
    https://tv.sohu.com/v/dXMvNDQyNjU3OTg4LzcwMjk5NjYzNS5zaHRtbA==.html
     

5. 锁优化建议

  • 减小同步范围:使用代码块而非整个方法。
  • 降低锁粒度:如 ConcurrentHashMap 的分段锁。
  • 避免嵌套锁:防止死锁。
  • 使用局部变量:线程私有,无需同步。

总结 synchronized 是 Java 最基础的同步机制,理解其使用方式与底层原理(锁升级、对象头、Monitor)对高效并发编程至关重要。后续可结合 java.util.concurrent 包中的高级工具(如 ReentrantLock)进一步优化。

赞(0)
未经允许不得转载:网硕互联帮助中心 » 深入解析synchronized锁机制
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!