java 中 synchronized 加在静态方法上锁的是该类的 class 对象实例。这意味着所有调用该静态方法的线程,无论来自哪个实例,只要它们属于同一个类加载器加载的类,就会竞争同一把锁。

实例方法与静态方法锁的区别是什么
实例方法锁的是当前对象实例(this),而静态方法锁的是类对象(ClassName.class)。这两把锁是完全独立的,互不干扰。

public class LockExample {
public synchronized void instanceMethod() {
System.out.println("Instance lock: " + Thread.currentThread().getName());
try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
public static synchronized void staticMethod() {
System.out.println("Static lock: " + Thread.currentThread().getName());
try { Thread.sleep(1000); } catch (InterruptedException e) {}
}
public static void main(String[] args) throws InterruptedException {
LockExample obj = new LockExample();
// 测试静态方法锁:不同实例也能互斥
Thread t1 = new Thread(() -> obj.staticMethod(), "Thread-1");
Thread t2 = new Thread(() -> new LockExample().staticMethod(), "Thread-2");
t1.start(); t1.join();
t2.start(); t2.join();
// 测试实例方法锁:不同实例不互斥
Thread t3 = new Thread(() -> obj.instanceMethod(), "Thread-3");
Thread t4 = new Thread(() -> new LockExample().instanceMethod(), "Thread-4");
t3.start(); t4.start();
t3.join(); t4.join();
}
}运行结果会显示 Thread-1 和 Thread-2 串行执行,而 Thread-3 和 Thread-4 并行执行。
立即学习“Java免费学习笔记(深入)”;
为什么静态同步方法能实现全局互斥
因为 JVM 为每个类维护一个唯一的 Class 对象作为监视器。当多个线程访问该类的任何静态同步方法时,它们都在尝试获取这个唯一的 Class 对象的监视器锁。这种机制确保了跨实例的全局互斥性,常用于单例模式的双重检查锁定或全局资源管理。

public class Singleton {
private static volatile Singleton instance;
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
// 预期输出:多次调用 getInstance() 始终返回同一对象引用上述代码展示了静态同步方法如何保证单例的唯一性。由于锁的是 Singleton.class,所有线程在创建实例前都必须等待锁释放,从而避免了并发创建多个实例的问题。


















