Synchronized、ReentrantLock 和 ReadWriteLock底层原理
2023-12-28 13:42:06
Synchronized 底层原理
1. JVM 层面的实现
? synchronized
是 Java 中的一个关键字,它提供了一种简单的策略来实现线程同步。在 JVM 层面,synchronized
可以依赖于对象内部的监视器锁(monitor lock)来实现同步。
- 锁的获取与释放:当一个线程进入?
synchronized
?修饰的方法或代码块时,它会自动获取锁,退出时自动释放锁。 - 对象头:Java 对象头中有一部分是用来实现锁的功能,称为 Mark Word。在运行时,Mark Word 中的信息会被用来存储锁的状态或者指向锁记录(Lock Record)的指针。
- 锁的状态:锁可以处于无锁状态、偏向锁状态、轻量级锁状态或重量级锁状态。随着竞争的增加,锁可以升级,但不会降级。
2. 锁的升级过程
- 偏向锁:当没有竞争出现时,默认开启偏向锁,它会偏向于第一个获取它的线程,减少之后的同步操作。
- 轻量级锁:当有其他线程尝试获取已被偏向的锁时,偏向锁会升级为轻量级锁,此时线程会在对象头上的 Mark Word 中创建锁记录。
- 重量级锁:当锁处于轻量级状态下,如果有更多线程加入竞争,轻量级锁会膨胀为重量级锁,此时线程会进入阻塞状态,等待操作系统的调度。
ReentrantLock 底层原理
1. Java API 层面的控制
? ReentrantLock
是 Java 中 java.util.concurrent.locks
包下的一个类。它提供了比 synchronized
更丰富的锁操作功能。
- 显式锁操作:使用?
ReentrantLock
?时,需要显示地调用?lock()
?和?unlock()
?方法来获取和释放锁。 - 可重入性:
ReentrantLock
?支持可重入,即同一个线程可以多次获得同一把锁。
2. AQS(AbstractQueuedSynchronizer)框架
? ReentrantLock
的实现依赖于 AQS,这是一个用于构建锁和其他同步组件的框架。
- 状态变量:AQS 内部有一个整型的状态变量来表示锁的状态。
- 节点队列:AQS 使用一个双向链表(称为 CLH 队列)来管理线程的排队工作。
- 独占模式:
ReentrantLock
?在 AQS 的基础上实现了独占模式,即任何时刻只有一个线程持有锁。
ReadWriteLock 底层原理
1. 分离读写操作
? ReadWriteLock
是一个接口,它的实现类(如 ReentrantReadWriteLock
)允许多个线程同时读取,但只有一个线程可以写入。
- 读锁和写锁:
ReadWriteLock
?提供了两种锁:读锁(共享锁)和写锁(独占锁)。
2. 基于 AQS 实现
? ReentrantReadWriteLock
的实现也是基于 AQS,但是它使用了 AQS 的共享模式。
- 状态变量的特殊使用:AQS 状态变量的高位表示写锁状态,低位表示读锁的数量。
- 锁降级:支持写锁降级为读锁,即持有写锁的线程可以获取读锁,然后释放写锁,这在某些情况下可以减少锁竞争。
总结
? Synchronized
、ReentrantLock
和 ReadWriteLock
都是用于实现线程同步的机制,但它们的实现原理和适用场景有所不同。Synchronized
是基于 JVM 实现的内置锁机制,而 ReentrantLock
和 ReadWriteLock
是基于 Java API 层面,通过 AQS 框架来实现更复杂的锁操作和同步控制。
文章来源:https://blog.csdn.net/u014745465/article/details/135266493
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!