对象锁锁的是this实例,类锁锁的是class对象;对象锁保护单个实例状态,类锁保护整个类的共享状态;二者互不干扰,可并发执行。

理解 synchronized 的对象锁和类锁,关键在于搞清“锁的是谁”——不是代码,而是某个具体的 Java 对象。锁的作用是串行化对共享资源的访问,而决定串行范围的,正是这个锁对象的身份。
对象锁:锁的是 this(当前实例)
当用 synchronized 修饰**非静态方法**,或写成 synchronized(this) { ... } 时,锁对象就是调用该方法的那个实例(this)。每个对象都有自己的独立锁,互不干扰。
- 两个线程调用同一个对象的同步实例方法 → 它们竞争同一把锁 → 互斥执行
- 两个线程调用不同对象的同步实例方法 → 各自持有自己的锁 → 可以同时执行
- 即使方法体完全一样,只要实例不同,就不存在锁冲突
类锁:锁的是 Class 对象
当用 synchronized 修饰静态方法,或写成 synchronized(YourClass.class) { ... } 时,锁对象是该类在 JVM 中唯一的 Class 实例(比如 String.class)。整个类所有实例共用这一把锁。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 无论多少个对象,只要调用该类的同步静态方法 → 都得排队等同一把类锁
- 一个线程在执行
static synchronized方法,另一个线程想进synchronized(A.class)块 → 同样被阻塞 - 类锁本质仍是对象锁,只是锁的对象换成了
Class类型的特殊对象
怎么选?看你要保护什么
对象锁保护的是单个实例的状态(如账户余额、缓存容器),类锁保护的是整个类的共享状态(如单例工厂、全局计数器、静态配置缓存)。
- 要保证“每个账户操作互不干扰” → 用对象锁(实例方法或
synchronized(this)) - 要保证“所有账户共用的连接池不被重复初始化” → 用类锁(静态方法或
synchronized(Xxx.class)) - 避免用
this作锁对象暴露给外部(可能被其他代码误锁),推荐用私有 final 锁对象,例如:private final Object lock = new Object(); synchronized(lock) { ... }
一个小陷阱:对象锁 ≠ 类锁,两者不互斥
一个线程持有着某个对象的实例锁,另一个线程完全可以同时获取该类的类锁;反之亦然。它们是两把完全独立的锁。
-
new X().doInstanceSync()和X.doStaticSync()可以并发执行 - 只有当多个线程试图获取同一把锁对象时,才会发生等待
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










