简体   繁体   中英

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. To make it thread safe I am using ReentrantLock . I have two conditions, (i) block a thread if the queue is empty and its trying to remove; (ii) block a thread if the queue is full and its trying to add. 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. I can do peek operation in ReentrantReadWriteLock but it doesn't come with condition variables which I need. Any suggestions?

Why does peek() need a lock at all?

It is impossible for peek() to give a guaranteed correct answer.

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. 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. You might need locking in that case to prevent the peek() method from following a bad pointer and crashing the program.

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().

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. this would allow you to see updates from peek() immediately. While I'm slightly novice at java, most languages achieve this by using something like the following:

query = &queue;

The & sign is the pass by reference operator.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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