虽然在没有线程竞争的情况下,使用锁似乎没有必要,但实际操作中,为了保持一致性和扩展性,JVM 和一些并发框架通常会使用锁(比如偏向锁)来保持一种规范和设计。
1. 代码设计的统一性和扩展性
假设你的程序今天只有一个线程,但是随着系统的发展,可能会引入多线程。如果一开始就完全没有锁机制,那么未来引入多线程时,可能会遇到同步问题,导致程序变得非常难以维护。为了解决这个问题,JVM 使用偏向锁来保证即使当前没有竞争的情况下,也能够快速、低开销地使用锁,保持未来扩展的兼容性。
举个例子:
- 你今天写了一个单线程的程序,程序中有很多共享资源,如果一开始没有使用任何锁,后期引入多线程时,修改代码的代价就非常大。
- 如果从一开始就使用偏向锁,那么随着线程数的增加,锁的机制能平滑过渡,避免了大规模重构。
2. JVM的内部优化
即使在单线程环境下,JVM 内部还是需要对对象进行一些管理(如对象标志位的管理)。在没有锁的情况下,JVM 内部也需要某种机制来确保对象状态的一致性。偏向锁作为一种轻量级的机制,它在保证线程安全的同时,开销较小。因此,JVM 会使用偏向锁来减少性能损失,同时为未来的扩展做好准备。
总结
- 偏向锁提供了一种在单线程和没有竞争的情况下高效、低开销的锁机制,它不仅可以减少获取锁的开销,还能为未来多线程竞争的情境做准备。
- 偏向锁是为了平衡性能和可扩展性,它避免了完全无锁带来的复杂性和不稳定性,同时也保持了在单线程执行时的低开销。