【问题标题】:Confused with custom read write lock implementation对自定义读写锁实现感到困惑
【发布时间】:2017-04-20 19:41:47
【问题描述】:

我在java 中使用wait/notify 看到了一些关于自定义read-write lock 实现的帖子。它看起来像:

 public class ReadWriteLock{

  private int readers;
  private int writers;
  private int writeRequests;

  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();
  }
}

我无法理解它是如何正确工作的,除非我没有正确理解 wait/notify 的真正工作原理。假设read 请求和Threads 更多,我的问题是:

    1234563因此,Thread 应该首先获得锁来执行此操作(如果我没记错的话)。只要read Thread调用wait,只有writeRequests或writers大于0,write Thread怎么有机会获得锁?
  • 基于上面的假设和陈述,多个read Threads怎么可能同时访问一个方法,因为他们应该首先调用lockRead(),这也是同步的?

【问题讨论】:

  • 你的方法是对的。我测试了你的代码,它工作正常。只是我需要知道当你使用 unlockRead 和 unlockWrite 方法时?
  • wait() 在它做它的时候释放锁。然后,lock* 操作必须与相应的unlock* 操作配对,例如rwl.lockRead(); try { /* ... */ } finally { rwl.unlockRead(); }。为什么unlockWrite 声明InterruptedException?

标签: java multithreading synchronization


【解决方案1】:

编辑:在看到您对问题进行编辑后,您问的是当多个线程在同一同步块内调用 wait() 时会发生什么 - 请参阅此以获取有关所谓“释放监视器”的详细说明 - @987654321 @

为了简化事情:

  • 同步方法类似于synchronized(this) 块。
  • 在synchronized 块内调用wait() 会释放锁并将线程切换到WAITING 状态。在这种情况下,其他线程可以获取同一对象上的锁,并可能通过使用等待的相同对象(在我们的例子中为this,因为您正在使用同步方法)
  • 如果您根据该原则映射调用每个方法的可能场景,您可以看到方法不是等待的(unlockRead()/unlockWrite()) - 这意味着它们可以在进入时阻止互斥,但不要' t 运行任何阻塞代码(并迅速结束)。 或者,它们正在等待但非阻塞(lockRead()/lockWrite())——就像解锁方法一样,它们的执行可能会被停止,但它们不会阻塞,而是在这种情况下等待。
  • 因此,在任何情况下,您都可以将您的代码视为非阻塞代码,因此它不会造成任何实际问题(至少我看不到任何问题)。
  • 也就是说,您应该防止解锁不存在的锁,因为这会导致计数器低于 0 的不良行为(这反过来会影响锁定方法)

【讨论】:

  • 我的问题是上面的代码如何按预期工作,因为整个逻辑在于同步方法,只能由一个线程同时访问。此外,在同一资源上同步的方法会相互排斥。
  • @arjacsoh 我看到了您的编辑并更新了我的答案以引用描述合作锁定的链接
  • @arjacsoh 我更新了我的答案以简化一些事情
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多