lock() 是线程同步动作,== 是值或引用比较,二者分属不同语义层:前者通过 aqs 抢占临界区,后者仅作判断,关键在于开发者是否厘清“资源调度”与“状态比较”的意图边界。

lock() 方法和 == 运算符根本不在同一逻辑层——前者是线程同步行为,后者是值比较语义。所谓“分水岭”,不是它们之间有调用关系或执行顺序之争,而是开发者是否清楚自己当前操作的是原始状态控制,还是对象引用/内容判断。
lock() 干的是什么
它是一个显式加锁动作,本质是请求进入临界区的许可:
- 底层依赖 AQS(AbstractQueuedSynchronizer)的 CAS + 队列机制
- 调用
lock()时,线程会尝试修改同步状态(state 变量),成功则获得锁;失败则入队、挂起或自旋 - 它不返回布尔值,也不做任何比较,只负责“抢占”与“等待”
== 在锁场景中常被误用的地方
== 本身不参与锁的获取或释放,但它常出现在锁相关判断里,比如:
-
if (lock.isLocked() == true)—— 没问题,但冗余,直接if (lock.isLocked())更自然 -
if (someObject == null)判断是否为 null,和锁无关,但若写成if (lock == null)却忘了初始化,就会 NPE - 最典型误区:用
==去比较两个ReentrantLock实例是否“是同一把锁”——这其实是比引用地址,而非锁状态;真正要看是否被占用,该用isLocked()或getHoldCount()
真正的分水岭:类型与语义边界
关键不在语法,而在建模意识:
- 当你在操作锁对象本身(如
lock.lock()、lock.unlock()),你是在调度线程行为,此时不涉及== - 当你在检查锁的状态(如
lock.isHeldByCurrentThread()返回true/false),这是 API 设计好的布尔结果,用== true不错,但没必要 - 当你在判断共享变量(如
status == READY),且status是int或enum ordinal,==合理;若status是String或自定义对象,就必须用equals()
一句话总结
lock() 是动词,代表一次同步动作;== 是谓词,只适合基本类型或明确需比地址的场景。它们的“分水岭”不在 JVM 执行流程里,而在你写代码那一瞬间——你心里想的到底是“我要抢资源”,还是“这两个值是不是一样”。跨不过去,不是语法错,是意图没表达清楚。











