如何等待与数据的ReentrantReadWriteLock?(How to wait for da

2019-07-02 16:47发布

据说,那ReentrantReadWriteLock是为一个作家和多个阅读器。

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

因此,要锁定什么?

我创建并发对象,如如下:

private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
protected final Lock readLock = rwl.readLock();
protected final Lock writeLock = rwl.writeLock();
protected final Condition hasData = writeLock.newCondition();

现在在写方法我做的:

writeLock.lock();

// writing first portion and updating variables

hasData.signalAll();

// if required then writing second portion and updating variables

hasData.signalAll();

但是,如何写一个阅读器? 如果它仅获得readLock ? 但如何能等待那么一个信号? 如果还aquires一个writeLock又在哪里是至上FO读/写锁?

如何保证,如果他们只保护在读取过程中所需的变量不会改变writeLock

QUEUES不匹配任务

这是关于这个问题ReentrantReadWriteLock

Answer 1:

该的ReentrantReadWriteLock确实有点混乱,因为readLock不具备的条件。 你必须升级到你的读者一个writeLock只等待状态。

在作家。

writeLock.lock(); //locks all readers and writers
// do write data
hasData.signalAll();
writeLock.unlock();

在读者你做:

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
}

为完整起见,每个解锁()应该是当然在最终块。



Answer 2:

但是,如何写一个阅读器? 如果它仅获得readLock? 但如何能等待那么一个信号? 如果还aquires一个writeLock又在哪里是至上FO读/写锁?

我切换到使用BlockingQueue ,将照顾这一切为您服务。 您的读者可以致电queue.take()哪些块等待在那里排在队列中的元素。

您的作者是有点复杂。 我会做的是类似如下:

// 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应该很好地工作。



Answer 3:

你不能达到使用具有阻断行为原语非阻塞的行为。 如果你真的想要的作家“写,从来没有等待任何人”,他甚至不应该知道你mentionned存在的锁。

当你执行

 rwl.writeLock().lock();

如果有读者操作,笔者将等待。

你应该尝试使用免费的等待(至少无锁)原语,如果你要尊重“永远等待”状态。 例如,使用的ConcurrentLinkedQueue和锁定机构将只用于管理阅读器之间的竞争条件。



Answer 4:

你需要的是LinkedBlockingQueue 它提供两个单独的锁 takeLockputLock

Offerput排队的方法总是使用putLock其中作为take方法总是使用takeLock



文章来源: How to wait for data with ReentrantReadWriteLock?