ReentrantReadWriteLock出现的原因
- 首先synchronized和ReentrantLock都是互斥锁,一个线程在获取锁资源之后另一个线程只能等待
- 假设有一种情况是读多写少,并且确保线程安全。可以使用ReentrantReadWriteLock实现
- ReentrantReadWriteLock的特点是读读不互斥,可以并发执行;写操作则是互斥的
代码效果显示
/**
* @author 舒一笑
* @date 2023/6/1
*/
public class Test17 {
static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
static ReentrantReadWriteLock.WriteLock writeLock = lock.writeLock();
static ReentrantReadWriteLock.ReadLock readLock =lock.readLock();
public static void main(String[] args) throws InterruptedException {
new Thread(() -> {
// 这里现在是读锁
readLock.lock();
try {
System.out.println("子线程是读锁");
Thread.sleep(50000000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}finally {
readLock.unlock();
}
}).start();
Thread.sleep(1000);
// 这里现在也是读锁
readLock.lock();
try {
System.out.println("主线程");
} finally {
readLock.unlock();
}
}
}
-
效果演示
-
前面是写锁效果演示
ReentrantReadWriteLock(重新输入读写锁定)锁的实现原理分析
-
还是基于AQS实现,同样都是对state的操作。获取锁资源成功便执行判断之后的方法体逻辑,否则便会阻塞到AQS队列中去排队
-
查看对AQS方法在ReentrantReadWriteLock中的实现可以知道
-
读锁操作是基于state的高16位的操作
-
写锁操作是基于state的低16位的操作,所以在锁重入的时候同样是对state的操作,但是范围却比小了
-
ReentrantReadWriteLock依旧是可重入锁
-
tryAcquire(int acquires)方法的分析
-
当前线程不持有锁资源,c的值是0;尝试获取锁资源、CAS拿锁。
写锁释放锁流程和源码分析
- tryRelease(arg)方法分析
读锁分析
- 读锁加锁源码分析
- 方法体里面没拿到锁资源就去排队