synchronized原理是什么?
synchronized的核心是基于Java 对象的监视器锁monitor lock,也称为互斥锁。每个 Java 对象都有一个与之关联的监视器锁,当线程尝试进入synchronized 块时,它会检查对象的监视器锁是否被其他线程持有(基于 Java 对象头中的一个字段,称为mark word,这个字段存储了对象的元数据,包括锁状态、锁的拥有者线程ID等信息)。 如果锁未被其他线程持有,当前线程会获取锁,并将锁标记为“已锁定”状态。如果锁已经被其他线程持有,当前线程会进入阻塞状态,直到锁被释放。当线程退出synchronized块时,它会释放锁,允许其他线程获取该锁。
当使用synchronized时,Java 编译器会将同步代码块转换为字节码指令。以下是synchronized 的字节码实现细节:
//示例代码
public class SyncExample {
public synchronized void synchronizedMethod() {
System.out.println("Synchronized Method");
}
}
//字节码分析
//使用 javap -c 命令查看字节码:
public synchronized void synchronizedMethod();
Code:
0: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #3 // String Synchronized Method
5: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
在进入 synchronized 块时,JVM 会插入 monitorenter 指令,用于获取对象的监视器锁。 在退出 synchronized 块时,JVM 会插入 monitorexit 指令,用于释放监视器锁。如果 synchronized 块中发生异常,JVM 会确保在异常传播之前执行 monitorexit 指令,以释放锁,这通过字节码中的异常处理表(Exception Table)实现。monitorenter 和 monitorexit JVM 还提供了多种优化机制(如自旋锁、锁粗化、锁消除和锁偏向)来提高 synchronized 的性能。
synchronized锁的过程,轻量级重量级有了解吗?
- 轻量级锁:轻量级锁是 synchronized 的默认锁状态,它使用一种称为“自旋锁”的机制。自旋锁的核心思想是让线程在等待锁释放时进行循环(自旋),而不是直接进入阻塞状态。这种方式在锁竞争不激烈的情况下可以减少线程上下文切换的开销。
-
重量级锁:当轻量级锁竞争激烈时(即多个线程频繁地尝试获取同一个锁),轻量级锁会膨胀为重量级锁。重量级锁使用操作系统的互斥量,使得其他线程在尝试获取锁时会被阻塞,直到持有锁的线程释放锁并唤醒等待的线程。
锁的升级过程:
- 无锁状态:初始状态,锁标志位表示未被锁定。
- 偏向锁:第一个线程获取锁时,锁升级为偏向锁,记录线程标识。
- 轻量级锁:当其他线程尝试获取偏向锁时,偏向锁撤销,锁升级为轻量级锁。
- 重量级锁:当轻量级锁竞争激烈时,锁膨胀为重量级锁。
关注公众号:咖啡Beans
在这里,我们专注于软件技术的交流与成长,分享开发心得与笔记,涵盖编程、AI、资讯、面试等多个领域。无论是前沿科技的探索,还是实用技巧的总结,我们都致力于为大家呈现有价值的内容。期待与你共同进步,开启技术之旅。