简体   繁体   English

具有条件变量的读写锁

[英]Read write lock with condition variables

I have a fifo queue that I have implemented, it has two methods add() and remove() both of which perform write operation on queue. 我有一个已实现的fifo队列,它有两个方法add()remove()都对队列执行写操作。 To make it thread safe I am using ReentrantLock . 为了使其线程安全,我正在使用ReentrantLock I have two conditions, (i) block a thread if the queue is empty and its trying to remove; 我有两个条件:(i)如果队列为空并尝试删除,则阻塞线程; (ii) block a thread if the queue is full and its trying to add. (ii)如果队列已满并且正在尝试添加,则阻塞线程。 Now, I want to implement a peek operation, which would allow multiple threads to perform simultaneous peeks but no thread would be able to write. 现在,我想实现一个窥视操作,该操作将允许多个线程同时执行窥视,但是没有线程能够写。 If I use ReentrantLock I cannot achieve that since I have to acquire the lock and its mutually exclusive. 如果我使用ReentrantLock我将无法实现,因为我必须获取锁及其互斥。 I can do peek operation in ReentrantReadWriteLock but it doesn't come with condition variables which I need. 我可以在ReentrantReadWriteLock进行窥视操作,但是它没有我需要的条件变量。 Any suggestions? 有什么建议么?

Why does peek() need a lock at all? 为什么peek()根本需要锁?

It is impossible for peek() to give a guaranteed correct answer. 这是不可能peek()给予保证正确的答案。

if (q.peek() != NULL) {
    ... q could be empty at this point because some other consumer
        could have removed the last item after the peek() returned...
} else {
    ... q could be non-empty at this point because a consumer could
        have added new items after the peek() returned...
}

The peek() method is somewhat more useful if there is only one consumer. 如果只有一个使用者,peek()方法会更有用。 In that case: 在这种情况下:

if (q.peek() != NULL) {
    ...q MUST be non-empty here, because there is no other thread that 
       could have removed anything from the queue...
}

Of course, one reason why peek() might need a lock is if you implement a linked queue. 当然,为什么peek()可能需要锁定的一个原因是如果您实现了链接队列。 You might need locking in that case to prevent the peek() method from following a bad pointer and crashing the program. 在这种情况下,您可能需要锁定,以防止peek()方法遵循错误的指针并导致程序崩溃。

If you're just looking for a solution, a quick fix would be to create a duplicate array (queue) before releasing the lock but after each update. 如果您只是在寻找解决方案,快速解决方案是在释放锁之前但在每次更新之后创建一个重复的数组(队列)。 This array could be your reference variable for peek(). 该数组可以作为peek()的参考变量。

I'm not sure if java supports this while threading, but you could create another variable, say query, that is a reference to the original queue. 我不确定java在线程化期间是否支持此功能,但是您可以创建另一个变量,例如query,它是对原始队列的引用。 this would allow you to see updates from peek() immediately. 这样您就可以立即查看peek()的更新。 While I'm slightly novice at java, most languages achieve this by using something like the following: 虽然我是Java的新手,但是大多数语言都是通过使用以下内容来实现此目的的:

query = &queue;

The & sign is the pass by reference operator. &符号是按引用传递的运算符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM