synchronized 不能替代全局变量,而是保护其线程安全访问;static 变量和共享实例变量需同步,优先用 AtomicInteger 等原子类,锁对象须唯一且静态。

直接用 synchronized 不能“替代”全局变量,而是用来保护对全局变量(尤其是静态变量)的读写操作,防止多线程并发修改导致数据错乱。关键不是去掉全局变量,而是让访问它的代码线程安全。
明确哪些变量需要保护
Java 中真正引发线程安全问题的,主要是以下两类:
-
static 变量:所有线程共享同一份内存,比如
private static int counter = 0; - 被多个线程共用的实例变量:例如单例对象里的字段、Spring 管理的 prototype 外部持有的共享对象等
如果只是每个线程自己 new 一个对象,里面的普通成员变量(非 static)默认就是线程私有的,不用加锁。
用 synchronized 保护静态变量的典型写法
对全局计数器这类场景,推荐两种等效但语义更清晰的方式:
立即学习“Java免费学习笔记(深入)”;
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 用 静态同步方法:
public static synchronized void increment() { globalCount++; } - 用 Class 对象显式加锁:
public static void increment() { synchronized(MyClass.class) { globalCount++; } }
两者效果一致,都锁住整个类,确保所有线程串行修改 globalCount。避免误用实例方法同步——那只会锁住当前对象,对静态变量无效。
比 synchronized 更优的替代方案
对于简单状态(如计数、标志位),优先考虑无锁原子类,它们性能更好、代码更简洁:
- 计数器 → AtomicInteger:
private static AtomicInteger counter = new AtomicInteger(0);
counter.incrementAndGet(); - 布尔开关 → AtomicBoolean
- 引用更新 → AtomicReference<T>
这些类内部基于 CAS 实现,没有阻塞开销,且天然支持复合操作(如 compareAndSet),比手写 synchronized 更可靠。
慎用同步块,注意锁对象一致性
若必须用 synchronized 块(比如要保护一段复杂逻辑),务必保证:
- 所有访问该全局变量的地方,都使用同一个锁对象;
- 不要用可变或局部对象作锁(如
new Object()或方法内声明的变量); - 推荐用 private static final Object LOCK = new Object(); 作为专用锁。
例如:
private static final Object LOCK = new Object();
public static void updateConfig() { synchronized(LOCK) { loadFromDB(); applyRules(); } }

















