您的位置:首页 > 编程语言 > Java开发

Java常见Lock(三): lock之ReadWriteLock、ReentrantReadWriteLock

2017-10-26 18:26 260 查看

ReadWriteLock

public interface ReadWriteLock

ReadWriteLock 维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。

只要没有 writer,读取锁可以由多个 reader 线程同时保持。写入锁是独占的。

与互斥锁相比,读-写锁允许对共享数据进行更高级别的并发访问。

接口定义方法

Lock readLock()返回用于读取操作的锁。
Lock writeLock()返回用于写入操作的锁。

ReentrantReadWriteLock

public class ReentrantReadWriteLock implements ReadWriteLock, java.io.Serializable

支持与 ReentrantLock 类似语义的 ReadWriteLock 实现。

支持公平模式和非公平模式两种策略,默认非公平模式。

此锁最多支持 65535 个递归写入锁和 65535 个读取锁。试图超出这些限制将导致锁方法抛出 Error。

适用于读多写少且对同步有要求的场景。

重入

  此锁允许 reader 和 writer 按照 ReentrantLock 的样式重新获取读取锁或写入锁。在写入线程保持的所有写入锁都已经释放后,才允许重入 reader 使用它们。

锁降级

  重入还允许从写入锁降级为读取锁,其实现方式是:先获取写入锁,然后获取读取锁,最后释放写入锁。但是,从读取锁升级到写入锁是不可能的。

锁获取的中断

  读取锁和写入锁都支持锁获取期间的中断。

Condition 支持

  写入锁提供了一个 Condition 实现,对于写入锁来说,该实现的行为与 ReentrantLock.newCondition() 提供的 Condition 实现对 ReentrantLock 所做的行为相同。当然,此 Condition 只能用于写入锁。

  读取锁不支持 Condition,readLock().newCondition() 会抛出 UnsupportedOperationException。

监测

  此类支持一些确定是保持锁还是争用锁的方法。这些方法设计用于监视系统状态,而不是同步控制。

此类行为的序列化方式与内置锁的相同:反序列化的锁处于解除锁状态,无论序列化该锁时其状态如何。

非公平模式连续竞争的非公平锁可能无限期地推迟一个或多个 reader 或 writer 线程,但吞吐量通常要高于公平锁。
公平模式当释放当前保持的锁时,可以为等待时间最长的单个 writer 线程分配写入锁,如果有一组等待时间大于所有正在等待的 writer 线程 的 reader 线程,将为该组分配写入锁。

成员变量

/** 内部类 readlock */
private final ReentrantReadWriteLock.ReadLock readerLock;
/** 内部类 writelock */
private final ReentrantReadWriteLock.WriteLock writerLock;
/** 内部类同步机制 */
private final Sync sync;


ReentrantReadWriteLock.ReadLock readLock():返回用于读取操作的锁。

public ReentrantReadWriteLock.ReadLock  readLock()  {
return readerLock;
}


ReentrantReadWriteLock.WriteLock writeLock():返回用于读取操作的锁。

public ReentrantReadWriteLock.WriteLock writeLock() {
return writerLock;
}


WriteLock、ReadLock

public static class ReadLock implements Lock, java.io.Serializable

public static class WriteLock implements Lock, java.io.Serializable

ReentrantReadWriteLock内部类,提供读写锁相关的支持。

ReadLock

void lock()获取读取锁。
void lockInterruptibly()获取读取锁,除非当前线程被 中断。
boolean tryLock()仅当写入锁在调用期间未被另一个线程保持时获取读取锁。
boolean tryLock(long timeout,TimeUnit unit)如果另一个线程在给定的等待时间内没有保持写入锁,并且当前线程未被 中断,则获取读取锁。
void unlock()试图释放此锁。
Condition newCondition()因为 ReadLocks 不支持条件,所以将抛出 UnsupportedOperationException。
String toString()返回标识此锁及其锁状态的字符串。括号中的状态包括字符串 “Read locks =”,后跟读取锁的数量。
WriteLock定义方法与ReadLock类似,只不过一个是写、一个是读。但WriteLock多了两个方法:getHoldCount(查询当前线程保持写入锁的数量。), isHeldByCurrentThread(查询此写入锁是否由当前线程保持。),另外WriteLock支持newCondition方法。

其实ReentrantReadWriteLock和ReentrantLock类似,只不过将读写锁分离,且读取锁是共享的,写入锁是互斥的,允许从写入锁降级为读取锁,但是,从读取锁升级到写入锁是不可能的。底层都是基于CAS,支持公平和非公平两种策略模式。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: