热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么ReentrantReadWriteLock不能锁升级

原标题:为什么ReentrantReadWriteLock不能锁升级在ReentrantReadWriteLock中,锁是不可以升级的,只能降级。

原标题:为什么ReentrantReadWriteLock不能锁升级

ReentrantReadWriteLock中,锁是不可以升级的,只能降级。
也就是如果当前线程持有了ReadLock,那么就不能再获取WriteLock,但是,如果当前线程持有了WriteLock,可以直接获取ReadLock
下面用代码尝试一下:

Logger logger = Logger文章来源地址45522.htmlFactory.getLogger(this.getClass());
ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();
logger.info("线程:[{}],开始readLock",Thread.currentThread().getName());
readLock.lock();
l文章来源站点https://www.yii666.com/ogger.info("线程:[{}],readLock成功",Thread.currentThread().getName());
logger.info("线程:[{}],开始writeLock",Thread.currentThread().getName());
writeLock.lock();
logger.info("线程:[{}],writeLock成功",Thread.currentThread().getName(文章来源地址45522.html));

从打印结果可以看出来,程序阻塞在了writeLock.lock();这一行上。
锁升级失败
www.yii666.com面我们看一下WriteLock的加锁过程的部分源码:java.util.concurrent.locks.Reentwww.yii666.comrantReadWriteLock.Sync#tryAcquire
tryAcquire
当这个tryAcquire返回false时,就跟ReentrantLock的逻辑差不多了,最后各种判断条件都会失败,最后,程序会阻塞在这里:java.util.concurrent.locks.AbstractQueuedSynchronizer#parkAndCheckInterrupt
parkAndCheckInterrupt
用流程图来描述一下这个问题是这样的:
在这里插入图片描述
假如只有一个线程t1,当t1已经获取读锁之后,再次获取写锁,因为写锁在加锁时判断到当前锁已经被加过读锁读写互斥,所以写锁会等待读锁释放之后再加锁。但是因为读锁是被当前线程持有的,所以这个等待会无限的等待下去,最后就成了死锁。

来源于:为什么ReentrantReadWriteLock不能锁升级


推荐阅读
author-avatar
偽愛拋棄_514
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有