synchronized 关键字
synchronized 是 Java 最基本的同步机制,用于解决多线程并发访问共享资源的问题。
基本用法
修饰实例方法
锁住当前实例对象(this):
Java
public synchronized void method() {
// 同步代码,只有获取当前对象锁才能执行
}
修饰静态方法
锁住当前类的 Class 对象:
Java
public static synchronized void staticMethod() {
// 同步代码,锁住 Class 对象
}
同步代码块
明确指定锁对象:
Java
public void method() {
synchronized (this) { // 锁当前实例
// 同步代码
}
synchronized (lockObj) { // 锁指定对象
// 同步代码
}
synchronized (Class.class) { // 锁 Class 对象
// 同步代码
}
}
锁对象选择
| 锁类型 | 锁对象 | 适用场景 |
|---|---|---|
| 实例方法 | this(当前实例) | 实例级别的同步 |
| 静态方法 | Class 对象 | 类级别的同步 |
| 代码块 | 指定对象 | 精细控制锁范围 |
注意:锁对象必须不变。推荐使用
private final Object lock = new Object()作为专用锁对象。
锁升级机制
JVM 对 synchronized 进行了优化,锁会根据竞争情况逐步升级:
- 偏向锁:单线程重复获取,无同步开销
- 轻量级锁:多线程交替执行,CAS 自旋
- 重量级锁:竞争激烈,使用操作系统互斥量
锁升级过程不可逆,性能开销逐步增加。
注意事项
- 避免锁住可变对象:对象引用变化会导致锁失效
- 避免锁住方法参数:可能导致外部干扰
- 避免嵌套锁:可能引发死锁
- 尽量减小锁范围:只锁必要代码块
要点总结
- synchronized 是 JVM 内置锁,自动获取和释放
- 实例方法锁 this,静态方法锁 Class 对象
- 代码块可指定任意对象作为锁
- 锁升级:偏向锁 → 轕量级锁 → 重量级锁
- 锁对象推荐使用 private final 对象
- JDK 6 后性能已优化,与 ReentrantLock 差距很小
📝 发现内容有误?点击此处直接编辑