結論
**同步了訪問共享變量的代碼路徑,線程才安全。** 僅加 `synchronized` 不等於自動安全,需满足:
- 識別**共享可變狀態**(静态字段、堆上對象字段、數據庫記錄)。
- 對**所有**讀寫該狀態的代碼路徑加同步(同一把鎖)。
- 避免同步塊內調用外部/耗時操作(死鎖、性能)。
Web 场景解析
- 每請求一線程,若 Controller **無静态字段**、不操作共享緩存/單例狀態 → **天然線程安全**,無需同步。
- 有静态字段(如計數器、緩存 Map)→ 必須同步或用 `ConcurrentHashMap`/`AtomicLong`。
- 數據庫操作需事務保證原子性(`@Transactional`),而非 Java 級 `synchronized`(集群無效)。
常見誤區
| 誤區 | 正確理解 |
| 方法加 synchronized 就安全 | 只保護該方法內訪問**同一實例/類**的共享狀態,其他路徑訪問同狀態仍不安全 |
| 所有方法都加 synchronized | 嚴重降低並發度,應縮小鎖粒度、用無鎖數據結構 |
| synchronized 解決分布式并发 | 僅限單 JVM 進程,分布式需分布式鎖 |
最佳實踐
- 優先用 **不可變對象**、**線程封閉**、**無鎖容器**(`java.util.concurrent`)。
- 必須同步時:`ReentrantLock`、`StampedLock`、`synchronized`(JDK 6+ 優化極好)。
- 鎖保護的資源集合要清晰文檔化,避免遺漏路徑。
總結
「同步即安全」是**必要非充分條件**。線程安全的本質是**正確管理共享可變狀態的訪問協議**,工具只是手段。