- 所有已知的实现类:
ReentrantReadWriteLock
public interface ReadWriteLock
ReadWriteLock 维护一对关联的 locks ,一个用于只读操作,一个用于写入。 读锁 可以由多个读取器线程同时持有,只要没有写入器。 写锁 是排他性的。
所有 ReadWriteLock 实现必须保证 writeLock 操作的内存同步效果(如 Lock 接口中所指定)也适用于关联的 readLock 。也就是说,成功获取读锁的线程将看到在先前释放写锁时所做的所有更新。
与互斥锁相比,读写锁在访问共享数据时允许更高级别的并发。它利用了这样一个事实,即虽然一次只有一个线程(writer 线程)可以修改共享数据,但在许多情况下,任何数量的线程都可以并发读取数据(因此有 reader 线程)。从理论上讲,使用读写锁所允许的并发性增加会导致使用互斥锁的性能提升。实际上,这种并发性的增加只会在多处理器上完全实现,并且只有在共享数据的访问模式合适的情况下才能实现。
读写锁是否会比使用互斥锁提高性能取决于与修改数据相比读取数据的频率、读写操作的持续时间以及对数据的争用——即即同时尝试读取或写入数据的线程数。例如,一个集合最初填充了数据,此后很少被修改,同时被频繁搜索(例如某种目录)是使用读写锁的理想候选者。但是,如果更新变得频繁,那么数据大部分时间都被独占锁定,并且并发性几乎没有增加。此外,如果读取操作太短,读写锁实现的开销(本质上比互斥锁更复杂)会主导执行成本,特别是因为许多读写锁实现仍然通过一个序列化所有线程一小段代码。最终,只有分析和测量才能确定读写锁的使用是否适合您的应用程序。
尽管读写锁的基本操作很简单,但实现必须做出许多策略决策,这可能会影响给定应用程序中读写锁的有效性。这些策略的示例包括:
- 决定授予读锁还是授予写锁,当读写者都在等待时,在写者释放写锁的时刻。作者偏好很常见,因为写作预计会很短且不频繁。读者偏好不太常见,因为如果读者像预期的那样频繁和长寿,它会导致写入的长时间延迟。公平或“按顺序”实现也是可能的。
- 确定在读者处于活动状态且写入者正在等待时请求读锁的读者是否被授予读锁。对读者的偏好可以无限期地延迟作者,而对作者的偏好可以降低并发的可能性。
- 判断锁是否可重入:拥有写锁的线程能否重新获取?是否可以在持有写锁的同时获取读锁?读锁本身是可重入的吗?
- 写锁能否降级为读锁而不允许干预写入器?读锁能否升级为写锁,优先于其他等待的读者或写者?
- 自从:
- 1.5
- 参见:
-
方法总结