Reputation: 15219
If I have a ReentrantReadWriteLock
, and I use it as the lock in a synchronized block, can other threads still release their locks?
For example:
ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
public void doSomething() {
synchronized(lock) {
lock.readLock().lock();
// do stuff
lock.readLock().unlock();
}
}
If I call doSomething()
and another thread is already holding the read lock, can that thread release the read lock?
When I make the doSomething()
call, I'll synchronize on the ReentrantReadWriteLock
and then attempt to get the read lock. Since something is already holding the read lock, I will block until that lock is released. I am curious to know if the read lock can be released since I've synchronized on the lock itself.
Upvotes: 0
Views: 346
Reputation: 47994
It is fairly trivial to write an example that shows one thread holding the monitor on the actual lock object does not obstruct other threads from acquiring and releasing the read lock. (This is of course not actually documented so could in theory be different for an alternate Java implementation!)
public static void main(String[] args) throws Exception {
final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
synchronized (lock) {
lock.readLock().lock();
try {
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
@Override
public void run() {
lock.readLock().lock();
try {
System.out.println("foo");
} finally {
lock.readLock().unlock();
}
}
}).start();
}
Thread.sleep(500);
System.out.println("done");
} finally {
lock.readLock().unlock();
}
}
}
Upvotes: 0
Reputation: 27210
Synchronizing on a ReentrantReadWriteLock object seems like an incredibly bad idea. Your example is locking two completely independent locks. First, it locks the mutex that is built in to every object (in this case, the ReentrantReadWriteLock object), and then it locks the read lock.
Any time you see a lock, you should ask this question, "What is the invariant that the lock is supposed to protect?" That is another way of asking, "In what way could your data be corrupted if the lock wasn't there?"
OK, What does the synchronized(lock)
protect?
And, What does the lock.readLock().lock()
protect?
If both answers are the same, then why use two locks?
If it was up to me I wouldn't even include the read/write lock in the first place
You might as well change your example to this:
Object lock = new Object();
public void doSomething() {
synchronized(lock) {
// do stuff
}
As far as the code you have shown us goes, it wouldn't behave any differently. (Though, it might change how your example interacts with other code that you haven't shown us.)
Upvotes: 1