笔友城堡 - 可定义的个人主页

前言

简单记录一下Java中synchronized的相关知识点,记录于此,方便自己查阅。

正文

synchronized是 Java 内置的互斥同步机制,用来保证:

✅ 同一时刻,只有一个线程能执行被保护的代码

它解决的是:

synchronized的用法

修饰实例方法

锁的是当前实例对象(this)

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

等价于:

public void method() {
    synchronized (this) {
        ...
    }
}
修饰静态方法

锁Class对象

public static synchronized void method() {
    ...
}

等价于:

public static void method() {
    synchronized (MyClass.class) {
        ...
    }
}

✅ 锁的是Class对象

✅ 所有实例共享一把锁

同步代码块
synchronized (lockObject) {
    ...
}
  1. 锁粒度更小
  2. 性能更好

作用

synchronized能保证原子性、可见性和有序性。

原子性
count++;

这不是原子操作,等同于

#先加1
temp = count + 1

#然后赋值
count = temp

可以通过synchronized

synchronized (this) {
    count++;
}

保证不会被中断

可见性
  • 解锁前:把工作内存写回主内存
  • 加锁后:清空工作内存,重新读主内存

相当于隐式使用了主内存

有序性
  • synchronized 内的代码不能被重排序到外面
  • 但不能防止 synchronized 块之间的重排

只能对内部代码块有效!

常见问题

锁对象不能是 null
Object object = null;
synchronized (object) {
    //错误,运行后异常
} 

运行时异常

Caused by: java.lang.NullPointerException: Null reference used for synchronization (monitor-enter)

推荐:

private final Object lock = new Object();
String / Integer 常量池陷阱
synchronized ("LOCK") { 
    // 危险
}

虽然可以运行,但还是存在一些陷阱。

下面是不同做法的对比

做法是否安全说明
synchronized ("order_lock")❌ 不安全全局共享
synchronized (UUID.randomUUID())❌ 不安全每次都不一样
synchronized (new Object())❌ 不安全每次都是新锁
private static final Object LOCK = new Object()✅ 正确类级唯一
private final Object LOCK = new Object()✅ 正确实例级唯一
synchronized 不保证执行顺序
synchronized (a) {}
synchronized (b) {}

不能保证哪个线程先执行,只能保证代码块内的顺序。

嵌套锁 ≠ 死锁
synchronized (a) {
    synchronized (b) {}
}

✅ synchronized 是可重入的

❌ 但可能 死锁

synchronized void a() {
    b();
}
synchronized void b() {
}

✅ 同一线程可重复进入

✅ JVM 维护 锁计数器

小结

synchronized 是 JVM 层面的互斥锁,基于 monitor,支持锁升级,保证原子性、可见性和基本的线程安全。

参考文章

AI

相关网址

笔友城堡 - 可定义的个人主页

暂无评论

评论审核已启用。您的评论可能需要一段时间后才能被显示。

none
暂无评论...