java - ReadWriteLocks-(不可重入)它如何支持多个读者获取读锁

标签 java multithreading readwritelock

我在许多教程中遇到了以下 ReadWriteLock 的不可重入实现。

public class ReadWriteLock{

    private int readers       = 0;
    private int writers       = 0;
    private int writeRequests = 0;

    public synchronized void lockRead() throws InterruptedException{
      while(writers > 0 || writeRequests > 0){
        wait();
      }
    readers++;
    }

    public synchronized void unlockRead(){
      readers--;
      notifyAll();
    }

    public synchronized void lockWrite() throws InterruptedException{
      writeRequests++;

      while(readers > 0 || writers > 0){
        wait();
      }
      writeRequests--;
      writers++;
    }

    public synchronized void unlockWrite() throws InterruptedException{
      writers--;
      notifyAll();
    }
}

问题:

此类的对象(例如 lock )在所有读取器和写入器线程之间共享以实现同步。

假设读者 T1 调用 lock.lockRead() ,这样就获取了锁对象上的锁,Reader T2同时调用lockRead()在同一个物体上。但是T1已经锁定了对象,所以T2应该被阻塞并在队列中等待。

那么,代码是如何允许多个读者同时设置readLock的呢?

当我犯错时,请纠正我。

最佳答案

确实没有 2 个线程可以同时执行 lockRead() 方法的主体。但这对于读取器/写入器模式正常工作并达到预期性能来说并不是必需的。

重要的是,如果没有 Activity 的写入者(不调用 wait),lockRead() 方法会快速返回。当方法结束时锁被释放,从而允许另一个线程也获取读锁。

所以,是的,获取读锁的行为(增加readers)是序列化的。但它发生得太快了,所以效果很好。

举例说明:

private ReadWriteLock lock = new ReadWriteLock(); // this instance is shared by all threads

public void ReadSomething() {
    try {
        lock.lockRead(); // serialized, but very quick

        PerformWork(); // potentially slower, but is concurrent
    } finally {
        lock.unlockRead(); // serialized, but very quick
    }
}

如果 2 个线程尝试同时运行上述 ReadSomething() 方法,则确实只有一个线程能够执行 lock.lockRead() 一次。但是,一旦该方法为其中一个线程返回,第二个线程也将能够执行它。而且对 lock.lockRead() 的调用发生得非常快,您甚至无法注意到一个线程正在等待另一个线程。

重要的是两个线程都能够同时执行更耗时的 PerformWork()

关于java - ReadWriteLocks-(不可重入)它如何支持多个读者获取读锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38621687/

相关文章:

java - 将 Android 项目转换为 Java 项目

java - 使用多线程的生产者消费者程序

java - Android BluetoothSocket无法连接

c++ - 我可以从 opengl 的显示屏上调用我的回调函数吗

java - 奇怪的操作,应用程序完成后处理程序仍然调用

Java ReentrantReadWriteLock 请求

java - 从 Tomcat 7 到 Weblogic 10.3.5 的 War 部署不起作用

multithreading - 通过作业完成的 Powershell Throttle 多线程作业

Java:ReadWriteLock 和 ReentrantReadWriteLock 之间的区别

java - 我如何处理 MongoDB 中的贪婪写锁定?