当前位置: 首页 > 知识库问答 >
问题:

关于读写锁的查询

席弘图
2023-03-14

我正在深入研究 java 并发 API,并试图了解读写锁的有用性。javadoc说读写块维护一对锁,一个用于读取,另一个用于写入操作。虽然写锁定是线程的独占访问,但多个线程可以获取读锁定。因此,如果在读取部分,我们所做的只是读取操作,并且无论如何我们都提供多个线程访问,那么首先需要读锁吗?是否存在读写锁实际上有用的情况?

共有3个答案

南宫嘉
2023-03-14

使用只读锁的原因是,如果其他线程锁定了一个对象进行写入,则该对象的状态可能不一致,因此您根本不想在没有锁的情况下开始读取它。获取读锁可以确保(1)当您查看对象时,该对象处于一致状态,因为没有其他线程正在修改它;(2)在您完成查看之前,没有其他线程可以开始修改它。我们将读取锁作为一种单独的类型,因为如果通常有很多线程需要读取,但更新很少,那么读者可以同时查看。

邬安邦
2023-03-14

如果您在许多线程中读取数据,由于可见性问题,您可能看不到数据的最新变化。基于每个线程,有许多层可以缓存数据:不同层的CPU缓存、RAM访问缓冲区等等。你可以肯定,你总是在观察最新的状态。

写锁定功能更加强大,可提供访问的原子性以及最新更改的可见性。

这里使用不同种类锁的主要原因是为了能够获得足够的同步级别,而不会给其他线程带来太多的开销和锁。

是否存在读写锁实际有用的情况?

当您有一些内存中的数据(数组、集合或其他什么)时,它非常有用,这些数据被不同的线程查询了很多次,但是这些数据的更新很少发生。在这种情况下,拥有单独的锁(查询使用读锁,更新使用写锁)可能会给你带来显著的性能优势。

卫诚
2023-03-14

....首先需要什么来读锁

在阅读时,你需要防止作家获得锁…直到所有读者都读完。但另一个读取器获取锁是可以的。

在写入时,您需要阻止读取器获取锁…直到写入器完成。

(换句话说,可以有一个写入器,也可以有多个阅读器持有锁......但不能两者兼而有之。

出于描述的目的,将行为描述为两个锁是有帮助的。引擎盖下到底发生了什么...是特定于实现的。

是否存在读写锁实际有用的情况?

嗯,是的。在任何可以区分需要共享只读访问的线程和需要独占读写(或仅写)的线程的情况下,ReadWrite锁比简单的或基元互斥锁允许更多的并发性。

 类似资料:
  • 9.3. sync.RWMutex读写锁 在100刀的存款消失时不做记录多少还是会让我们有一些恐慌,Bob写了一个程序,每秒运行几百次来检查他的银行余额。他会在家,在工作中,甚至会在他的手机上来运行这个程序。银行注意到这些陡增的流量使得存款和取款有了延时,因为所有的余额查询请求是顺序执行的,这样会互斥地获得锁,并且会暂时阻止其它的goroutine运行。 由于Balance函数只需要读取变量的状态

  • 我有一个多线程的JEE应用程序,运行选择更新限制1;使用WHERE子句对表进行查询,并在每个事务中更新行,这将创建行级写锁,并且不会阻止读取器进行读取。 有什么方法可以配置postgres,来阻止读者用写锁读取行?

  • Go语言包中的 sync 包提供了两种锁类型:sync.Mutex 和 sync.RWMutex。 Mutex 是最简单的一种锁类型,同时也比较暴力,当一个 goroutine 获得了 Mutex 后,其他 goroutine 就只能乖乖等到这个 goroutine 释放该 Mutex。 RWMutex 相对友好些,是经典的单写多读模型。在读锁占用的情况下,会阻止写,但不阻止读,也就是多个 gor

  • 我有一个关于Firestore数据库中读/写的问题。情况是: 我有一个集合“城市”(例如20个城市),它有一个子集合“餐厅”(例如500家餐厅): 现在我的问题是:当我想得到一个城市中的所有餐厅时,FiRecovery会支付多少次读取费用?500? 当我想添加一家餐厅时:是否只需要写一封信就可以将此文档添加到子集合中?

  • 我正在使用spring-data、QueryDSL和MySQL。 返回所有包含姓名的员工(在first_name和last_name中),并从该结果中获得的证书在2014年12月22日至2015年12月22日之间 我尝试了它,但无法获得如何以QueryDSL方式迭代每个员工的每个证书并返回员工列表。 您的回应将非常感谢!!