【锁synchronized】在Java多线程编程中,`synchronized` 是一个非常重要的关键字,用于控制对共享资源的访问,防止多个线程同时修改共享数据导致的数据不一致问题。它通过实现“互斥锁”机制,确保同一时间只有一个线程可以执行某个代码块或方法。
一、synchronized 的作用
`synchronized` 主要用于以下两个方面:
功能 | 描述 |
线程同步 | 确保同一时刻只有一个线程可以执行被 `synchronized` 修饰的方法或代码块。 |
内存可见性 | 在进入和退出 `synchronized` 块时,会刷新线程本地缓存,保证变量的最新值对其他线程可见。 |
二、synchronized 的使用方式
`synchronized` 可以用于方法或代码块,具体形式如下:
使用方式 | 示例代码 | 说明 |
同步方法 | `public synchronized void method() { ... }` | 该方法被锁住,锁对象是当前实例(this)。 |
静态同步方法 | `public static synchronized void staticMethod() { ... }` | 锁对象是当前类的 Class 对象。 |
同步代码块 | `synchronized (obj) { ... }` | 锁对象可以是任意对象,灵活控制锁的范围。 |
三、synchronized 的底层实现
`synchronized` 是基于 Monitor(监视器)实现的,每个对象都有一个与之关联的 Monitor。当一个线程尝试进入一个被 `synchronized` 修饰的代码块时,它需要先获取对应的 Monitor。
- 进入 Monitor:线程需要竞争锁,成功获得后才能继续执行。
- 退出 Monitor:线程执行完同步代码块后,自动释放锁。
四、synchronized 的优缺点
优点 | 缺点 |
简单易用,适合基础并发控制 | 性能较低,不适合高并发场景 |
提供内存可见性保障 | 不支持中断、超时等高级功能 |
保证原子性和一致性 | 锁粒度较大,可能造成性能瓶颈 |
五、对比其他锁机制
锁类型 | 是否可重入 | 是否支持中断 | 是否支持超时 | 性能 | 适用场景 |
`synchronized` | ✅ | ❌ | ❌ | 中等 | 简单并发控制 |
`ReentrantLock` | ✅ | ✅ | ✅ | 更高 | 高级并发控制 |
`ReentrantReadWriteLock` | ✅ | ✅ | ✅ | 高 | 读多写少场景 |
六、总结
`synchronized` 是 Java 中最基础、最常用的线程同步机制,适用于大多数简单的并发场景。虽然它的性能不如 `ReentrantLock` 等高级锁,但其语法简洁、使用方便,仍然是开发中不可或缺的一部分。在实际开发中,应根据业务需求选择合适的锁机制,避免不必要的性能损耗和死锁风险。