SonarLint不反对synchronized本身,但会报错其不合理使用:锁对象须明确不可变(禁用String/包装类),同步范围应最小化(避免方法级锁),禁用空或无意义同步块,优先用volatile、原子类和线程安全集合替代。

Java中synchronized代码块本身不会直接触发SonarLint报错,但其使用方式若违背线程安全最佳实践或隐藏潜在缺陷,就会被标记为不合规。SonarLint关注的不是“用了synchronized”,而是“是否用得合理、安全、可维护”。
synchronized锁对象必须明确且不可变
SonarLint会检测锁对象是否为null、是否为可变引用(如String、Integer等常量池对象)、是否在同步块内被重新赋值。这些都会导致锁失效或死锁风险。
- 禁止用String字面量或基础类型包装类作锁:它们可能被JVM复用,造成意外的锁竞争
- 推荐使用private final Object lock = new Object();作为显式锁对象
- 避免对this或getClass()加锁——易被子类或反射干扰,SonarLint提示java:S2221
同步范围应最小化,避免方法级粗粒度锁
修饰整个方法的synchronized(尤其是static方法)容易成为性能瓶颈,SonarLint会标记为“可优化的同步粒度”(规则java:S2275)。
- 优先用同步代码块包裹真正需要保护的共享资源操作,而非整个方法体
- 若方法中仅部分逻辑需同步,拆分出临界区,其余逻辑移出synchronized块
- 避免在synchronized块内执行I/O、远程调用、长耗时计算等阻塞操作
禁止空同步块或无意义的同步
空的synchronized块(synchronized(lock) {})或仅包含不可变操作(如读取final字段)的同步块,会被SonarLint识别为冗余,违反java:S1143。
立即学习“Java免费学习笔记(深入)”;
- 检查同步块内是否真有共享状态读写——没有则删掉
- 若仅为内存可见性保障(如双重检查锁定中的volatile替代方案),应改用volatile字段+原子操作,更清晰安全
- 确认同步目标:是保护变量?还是保证操作原子性?意图不清即视为可疑
配合volatile和原子类,减少synchronized依赖
SonarLint鼓励用更轻量、语义更明确的并发工具替代synchronized,尤其在简单状态更新场景。
- 计数器、标志位、状态切换等,优先用AtomicInteger、AtomicBoolean等
- 已声明为volatile的布尔开关,不应再用synchronized二次保护
- 集合操作尽量选用ConcurrentHashMap、CopyOnWriteArrayList等线程安全容器


















