synchronized不是分布式锁,因其锁状态仅存于单个JVM的对象头和Monitor中,无法跨进程、跨机器感知或协调,故在分布式环境下完全失效。

Java 中用 synchronized 无法实现真正的分布式锁,它只能保证**单个 JVM 进程内**的线程互斥,跨进程、跨机器时完全无效。所谓“分布式锁的本地版”,通常是指在**单机多线程场景下模拟分布式锁的行为逻辑(比如可重入、带超时、支持释放)**,但底层仍依赖 synchronized —— 这本质上是“本地锁的增强版”,不是分布式锁。
为什么 synchronized 不是分布式锁
synchronized 的锁信息保存在 JVM 的对象头或 Monitor 中,只对当前 JVM 可见。不同 Java 进程、不同服务器上的线程彼此看不到对方持有的锁,自然无法协调。
- 两台服务器各起一个 Spring Boot 应用,都执行
synchronized(lockObj) { ... }→ 完全不互斥 - 同一台机器启动两个独立的 Java 进程 → 锁不共享,无任何同步效果
- 即使用了 Redis 或 ZooKeeper,只要没在代码中调用它们,
synchronized就和分布式毫无关系
用 synchronized 模拟“类分布式锁”的常见做法
如果目标是在单机多线程环境下,实现类似分布式锁的编程体验(比如:显式 tryLock、可重入、自动释放、避免死锁),可以封装一个基于 synchronized 的工具类:
- 用
ReentrantLock更合适(它原生支持tryLock(long, TimeUnit)、lockInterruptibly()等),但若坚持用synchronized,只能靠手动加标志 + volatile + 计数器模拟 - 典型结构:一个全局静态对象作为锁根,配合
ThreadLocal记录持有线程、进入次数(实现可重入)、开始时间(用于模拟超时) - 不推荐自行实现超时等待:synchronized 本身不支持中断或超时,强行用
wait(timeout)配合循环判断,易出错且违背初衷
真正该怎么做(轻量级替代方案)
如果只是单机多线程,又想要“锁的语义清晰 + 可控”,直接用 JDK 并发包更稳妥:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
-
ReentrantLock:支持公平/非公平、可中断、超时获取、条件队列 -
StampedLock:读多写少场景下性能更好,支持乐观读 - 需要“全局唯一锁名”控制粒度?用
ConcurrentHashMap<string reentrantlock></string>缓存命名锁(注意锁对象创建与清理,避免内存泄漏)
如果真要分布式锁,请换技术栈
一旦涉及多节点,必须借助外部协调服务:
- Redis + SETNX(或 Redission 封装的
RLock)→ 最常用,需处理锁续期、异常释放、Redlock 等细节 - ZooKeeper 临时顺序节点 → 强一致性,但运维成本高
- Etcd(Compare-And-Swap)→ 云原生场景越来越多见
这些方案的核心是:锁状态存储在所有节点都能访问的共享存储中,而不是每个 JVM 自己记一笔。

















