Reputation: 3752
I was wondering what the difference is between ReentrantLock
and ReentrantReadWriteLock
, in terms of logical difference. In other words, are there situations when you just need a lock without read/write locks and vice versa, read/write locks and just a lock is not sufficient?
Consider the following primary example that uses just a lock:
public class Counter {
private int counter = 0;
private ReentrantLock lock = new ReentrantLock(true);
public void increment() {
lock.lock();
counter += 1;
lock.unlock();
}
public int getCounter() {
return counter;
}
}
Consider, and compare it against the previous one, the following read/write lock example:
public class Counter {
private int counter = 0;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
public void increment() {
lock.writeLock().lock();
try {
counter += 1;
} finally {
lock.writeLock().unlock();
}
}
public int getCounter() {
lock.readLock().lock();
try {
return counter;
} finally {
lock.readLock().unlock();
}
}
}
Which of the two is the correct implementation in terms of thread-safety? And why?
Upvotes: 11
Views: 7626
Reputation: 11
ReentrantReadWriteLock
can provide higher performance when the read operations are more than write operations by controlling the AbstractQueuedSynchronizer$state
carefully.
If not, the overhead of controlling is higher than ReentrantLock
.
For your first example, it is right that you don't need to consider the atomicity problem for getCounter()
method ,but the visibility problem should be considered. A thread may see the initial value even if other thread have incremented the counter.
Upvotes: 0
Reputation: 121
Using ReentrantLock
or ReentrantReadWriteLock
depends on the use case you like to solve.
At your first example there is no lock at the getCounter()
method. So getting the counter is possible while a thread holds the ReentrantLock
at the increment method.
At your second example you can't get the counter while a thread holds the writeLock()
at the increment method. And holding a readLock()
prevents the counter increment. readLock()
may be held simultaneously by several threads reading your counter
param.
Upvotes: 3