参考博客:Java中ReentrantLock的使用(CSDN)
参考博客:Java并发编程之ReentrantReadWriteLock详解(CSDN)
参考博客:ReentrantReadWriteLock读写锁详解(博客园)
参考博客:ReentrantReadWriteLock读写锁详解(知乎)
ReentrantLock 可重入锁实现了 Lock 接口,是一种独占锁。公平与否取决于构造函数。
ReentrantReadWriteLock 可重入锁实现了 ReadWriteLock 接口,ReentrantReadWriteLock 读锁可以在没有写锁的时候被多个线程同时持有,写锁是独占的。公平与否取决于构造函数。
ReentrantReadWriteLock 中有两个内部静态类 ReadLock 和 WriteLock,他们都实现了Lock接口。
Lock接口中的方法:
// 不可中断的方式获得锁,获得锁后线程继续执行,否则阻塞,无法被interrput()方法中断。
void lock();
// 可中断的方式获得锁,获得锁后线程继续执行,否则阻塞,可以被interrput()方法中断。
void lockInterruptibly() throws InterruptedException;
// 尝试获得锁,获得锁以后返回ture,获取锁失败返回false。
boolean tryLock();
// 尝试获得锁,获得锁以后返回ture,超时以后返回false。
boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
// 释放锁。
void unlock();
// 创建Condition,用于多线程间通信。
Condition newCondition();
ReentrantLock中除实现Lock接口外的一些其他方法:
// 构造函数,创建一个非公平锁。
ReentrantLock()
// 构造函数,fair = true:创建一个公平锁;fair = false:创建一个非公平锁。
ReentrantLock(boolean fair)
// 查看正在抢锁的线程数量。
int getQueueLength()
// 是否有线程正在抢锁。
boolean hasQueuedThreads()
// 指定的线程是否在抢锁。
boolean hasQueuedThread(Thread thread)
// 当前线程是否抢到锁。返回0代表没有。
int getHoldCount()
// 当前是否有某个线程占有锁。
boolean isLocked()
// 是否为公平锁
boolean isFair()
ReentrantLock.Condition是在粒度和性能上都优于Object的notify()、wait()、notifyAll()线程通信的方式。
Condition中通信方法相对Object的通信在粒度上是粒度更细化,表现在一个Lock对象上引入多个Condition监视器、通信方法中除了和Object对应的三个基本函数外,更是新增了线程中断、阻塞超时的函数;
Condition中通信方法相对Object的通信在性能上更高效,性能的优化表现在ReentrantLock比较synchronized的优化 ;
注意在使用Condition的await()、signal()、signalAll()方法时不能和Object的wait()、notify()、notifyAll()混用,否则抛出IllegalMonitorStateException;
Condition接口中的一些方法:
// 当前线程进入阻塞状态,允许其他线程抢占当前线程持有的lock锁。
// 可以被interrupt()方法中断,抛出InterruptedException异常,捕获异常后线程继续执行。
// 可以被signal()方法或者signalAll()方法唤醒,线程继续执行。
void await() throws InterruptedException;
// 当前线程进入阻塞状态,允许其他线程抢占当前线程持有的lock锁。
// 不可以被interrupt()方法中断。
// 可以被signal()方法或者signalAll()方法唤醒,线程继续执行。
void awaitUninterruptibly();
// 当前线程进入阻塞状态&