5

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

4

3 回答 3

3

如果您在多个线程中读取数据,由于可见性问题,您可能看不到数据的最新更改。有许多层可以在每个线程的基础上缓存数据:不同层的 CPU 缓存、RAM 访问缓冲区等。您可以肯定,将读取锁定到位,您始终在观察最新状态。

写锁甚至更强大,提供了访问的原子性以及最新更改的可见性。

这里使用不同类型的锁的主要原因是能够获得足够的同步级别,而不会为其他线程引入过多的开销和锁。

是否存在读写锁真正有用的场景?

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

于 2013-08-12T08:01:55.023 回答
3

....首先需要读锁

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

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

(换句话说,可以有一个作家,或多个持有锁的读者......但不能同时拥有。)

为了描述这一点,将行为描述为两个锁会很有帮助。幕后实际发生的事情......是特定于实现的。


是否存在读写锁真正有用的场景?

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

于 2013-08-12T08:02:17.113 回答
1

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

于 2013-08-12T08:02:17.440 回答