ReentrantReadWriteLock中,为什么在获取写锁前要释放读锁,查的说会产生死锁,不太明白
来源:6-6 J.U.C之AQS-ReentrantLock与锁-2
![](http://img1.sycdn.imooc.com/user/54cf7c5b0001c8de01800180-100-100.jpg)
茶铺里的水
2018-03-29
* class CachedData { * Object data; * volatile boolean cacheValid; * final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); * * void processCachedData() { * rwl.readLock().lock(); * if (!cacheValid) { * // Must release read lock before acquiring write lock * rwl.readLock().unlock(); * rwl.writeLock().lock(); * try { * // Recheck state because another thread might have * // acquired write lock and changed state before we did. * if (!cacheValid) { * data = ... * cacheValid = true; * } * // Downgrade by acquiring read lock before releasing write lock * rwl.readLock().lock(); * } finally { * rwl.writeLock().unlock(); // Unlock write, still hold read * } * } * * try { * use(data); * } finally { * rwl.readLock().unlock(); * } * } * }}
写回答
1回答
-
你好,Reentrant代表重入,字面意思这是一个可重入的读写锁。这里的读写锁都可重入, 线程可同时具有读写锁。
获取 writeLock 时 一定是在没有线程获取 readLock 或 writeLock 时才获取成功,取 readLock 的过程中, 若此时有线程已获取写锁 或 同步等待队列 里面有获取 writeLock 的线程, 则一定会等待获取writeLock成功并释放或放弃获取 后才能获取(死锁时, 已获取 readLock 的线程还能重复获取 readLock)
基于上面的特性,我们再来说死锁的问题:
线程A获取 readLock 成功,然后开始获取 writeLock, 这时发现 readLock 已经 readLock 已经被线程获取, 且writeLock没有被人获取(方法 tryAcquire c != 0 && w == 0), 直接加入到同步等待队列 里面, 并且一直等待 readLock 的释放(等待自己readLock释放, 其实是不可能的)
线程B之后第一次获取 readLock, 此时同步等待队列里面有等待的节点, 就在那一直等待。
死锁就出现了。
112018-03-29
相似问题