package java.util.concurrent.locks;
/**
* ReadWriteLock维护一对相关联的锁,一个用于只读操作,一个用于写操作。
* 读锁可以被多个读线程同时持有,只要没有写线程。写锁是排他的。
*
* <p>所有的ReadWriteLock实现必须保证writeLock操作的内存同步效果(在Lock接口中指定)也与相关的readLock保持一致。
* 也就是说,一个成功获得读锁的线程将看到在之前释放写锁时所做的所有更新。
*
* <p>读写锁在访问共享数据时比互斥锁允许的并发级别更高。
* 它利用了这样一个事实:
* 虽然一次只有一个线程(写线程)可以修改共享数据,但在许多情况下,任意数量的线程都可以并发地读取数据(因此称为reader线程)。
* 从理论上讲,与使用互斥锁相比,使用读写锁所允许的并发性的增加将导致性能的改进。
* 在实践中,这种并发性的增加只能在多处理器上完全实现,而且只有在共享数据的访问模式合适的情况下才会实现。
*
* <p>读写锁是否会提高性能在使用互斥锁的频率取决于读取和修改的频率和持续时间,以及他们的竞争-
* 也就是说,在同一时间,试图读或写数据的线程数量。
* 例如,一个集合最初是用数据填充的,之后很少被修改,但经常被搜索(比如某个目录),这是使用读写锁的理想选择。
*
* 然而,如果更新变得频繁,那么数据的大部分时间都被独占锁定,如果并发性有所增加的话,那么锁定的时间就很少。
* 此外,如果读操作太短,读写锁实现的开销(它本质上比互斥锁更复杂)会占用执行成本,特别是许多读写锁实现仍然通过一小段代码序列化所有线程。
* 最终,只有分析和度量才能确定读写锁的使用是否适合您的应用程序。
*
*
* <p>尽管读写锁的基本操作很简单,但实现必须做出许多策略决策,这些决策可能会影响给定应用程序中读写锁的有效性。
* 这些政策的例子包括:
* <ul>
* <li>决定是否授予读锁或写锁,当读和写都在等待时,当写释放写锁。
* 写的偏好是常见的,因为写的内容应该是简短和不频繁的。
* 读的偏好不太常见,因为如果读者像预期的那样频繁且长寿,它会导致写操作的长时间延迟。
* 公平的,或“按顺序”的实现也是可能的。
*
* <li>判断当reader处于活动状态且writer正在等待时,是否有reader请求读锁,则授予读锁。
* 优先选择读取器会无限期地延迟写入器,而优先选择写入器会降低并发的可能性。
*
* <li>确定锁是否可重入:有写锁的线程可以重新获取它吗?
* 它能在保持写锁的同时获得读锁吗?读锁本身是可重入的吗?
*
* <li>写锁是否可以降级为读锁而不允许写入者介入?
* 是否可以将读锁升级为写锁,而不是其他等待的读锁或写锁?
*
* </ul>
* 在评估一个给定实现对你的应用程序的适用性时,你应该考虑所有这些事情
*
* @see ReentrantReadWriteLock
* @see Lock
* @see ReentrantLock
*
* @since 1.5
* @author Doug Lea
*/
public interface ReadWriteLock {
/**
* 返回用来读取的锁
*
* @return the lock used for reading
*/
Lock readLock();
/**
* 返回用来写的锁
*
* @return the lock used for writing
*/
Lock writeLock();
}
java多线程 ReadWriteLock源码分析
猜你喜欢
转载自blog.csdn.net/xushiyu1996818/article/details/113523588
今日推荐
周排行