【问题标题】:Query regarding read-write locks关于读写锁的查询
【发布时间】:2013-08-13 11:17:03
【问题描述】:

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

【问题讨论】:

  • 你需要一个读锁,当线程持有写锁时它会阻塞。

标签: java multithreading java.util.concurrent


【解决方案1】:

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

在阅读时,您需要防止写入者获取锁……直到所有读取者都完成。但是另一个阅读器获取锁是可以的。

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

(换句话说,可以有一个写入器,或者多个读取器持有锁......但不能同时拥有。)

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


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

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

【讨论】:

    【解决方案2】:

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

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

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

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        猜你喜欢
        • 2011-05-08
        • 1970-01-01
        • 2011-01-25
        • 2011-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-24
        相关资源
        最近更新 更多