首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用ReentrantReadWriteLock等待数据?

如何使用ReentrantReadWriteLock等待数据?
EN

Stack Overflow用户
提问于 2012-10-26 13:59:35
回答 4查看 4.1K关注 0票数 6

据说,ReentrantReadWriteLock是为一位作家和多位读者设计的。

然而,读取器应该等到缓冲区中出现一些数据。

那么,该锁什么?

我创建了如下并发对象:

代码语言:javascript
复制
private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
protected final Lock readLock = rwl.readLock();
protected final Lock writeLock = rwl.writeLock();
protected final Condition hasData = writeLock.newCondition();

现在,在写方法中,我这样做:

代码语言:javascript
复制
writeLock.lock();

// writing first portion and updating variables

hasData.signalAll();

// if required then writing second portion and updating variables

hasData.signalAll();

但是如何写一个读者呢?它应该只收购readLock吗?但它怎么能等待信号呢?如果它也拥有一个writeLock,那么读/写锁的优势在哪里?

如果只受writeLock保护,如何确保所需变量在读取过程中不会更改?

队列与任务不匹配

这是关于ReentrantReadWriteLock的问题。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-10-26 15:01:08

ReentrantReadWriteLock确实有点混乱,因为readLock没有条件。您必须在读取器中升级到writeLock才能等待情况的发生。

在作家身上。

代码语言:javascript
复制
writeLock.lock(); //locks all readers and writers
// do write data
hasData.signalAll();
writeLock.unlock();

在读者中,你会:

代码语言:javascript
复制
readLock.lock(); //blocks writers only
try{
 if(!checkData()) //check if there's data, don't modify shared variables
 {
  readLock.unlock();
  writeLock.lock(); // need to lock the writeLock to allow to use the condition.
                    // only one reader will get the lock, other readers will wait here      
  try{
   while(!checkData()) // check if there' still no data
   {
     hasData.await(); //will unlock and re-lock after writer has signalled and unlocked.
   }
   readLock.lock();    // continue blocking writer
  }
  finally
  {
    writeLock.unlock(); //let other readers in
  }
 }
 //there should be data now
 readData(); // don't modify variables shared by readers.
}
finally
{
  readlock.unlock(); //let writers in
}

当然,为了完整性,每个解锁()都应该位于一个最终块中。

票数 7
EN

Stack Overflow用户

发布于 2012-10-26 14:10:53

但是如何写一个读者呢?它应该只收购readLock吗?但它怎么能等待信号呢?如果它也拥有一个writeLock,那么读/写锁的优势在哪里?

我会切换到使用一个BlockingQueue来处理所有这些问题。您的读者可以调用queue.take(),哪些块等待队列中的元素。

你的作家有点复杂。我要做的事情如下:

代码语言:javascript
复制
// initially try to put an element into the queue
if (!queue.offer(element)) {
   // if the queue is full then take an element off the head and just drop it
   // this won't block and may not remove anything due to race conditions
   queue.poll();
   // this put will never block because now there will be space in the queue
   queue.put(element);
}

如果有多个作者,这是行不通的。那么你需要一个synchronized锁。如果您处理的是一个固定大小的队列,那么ArrayBlockingQueue应该工作得很好。

票数 3
EN

Stack Overflow用户

发布于 2012-10-26 14:08:37

不能使用具有阻塞行为的原语来实现非阻塞行为。如果你真的想让作者“写作,从不等待任何人”,他甚至不应该知道你提到的锁是存在的。

当你执行

代码语言:javascript
复制
 rwl.writeLock().lock();

如果有读者在操作,作者会等待。

如果您想要尊重“永不等待”条件,您应该尝试使用无等待(至少是无锁)原语。例如,使用ConcurrentLinkedQueue和锁定机制,这将只用于管理读取器之间的争用条件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13088363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档