-
Bug
-
Resolution: Fixed
-
P4
-
6
-
b17
-
x86
-
windows_xp
-
Not verified
A DESCRIPTION OF THE PROBLEM :
In the following code sample, both calls to lock() should be followed by try {} finally blocks with calls to unlock(), otherwise "lock-leakage" and deadlock can result. Additionally, I'm not so sure "cacheValid" needs to be volatile since it's only accessed after lock acquisition.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
void processCachedData() {
rwl.readLock().lock();
try {
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have acquired
// write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
use(data);
} finally {
rwl.readLock().unlock();
}
}
ACTUAL -
void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
// Recheck state because another thread might have acquired
// write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
rwl.writeLock().unlock(); // Unlock write, still hold read
}
use(data);
rwl.readLock().unlock();
}
URL OF FAULTY DOCUMENTATION :
file:///C:/Java/jdk1.6.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html
In the following code sample, both calls to lock() should be followed by try {} finally blocks with calls to unlock(), otherwise "lock-leakage" and deadlock can result. Additionally, I'm not so sure "cacheValid" needs to be volatile since it's only accessed after lock acquisition.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
void processCachedData() {
rwl.readLock().lock();
try {
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have acquired
// write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
use(data);
} finally {
rwl.readLock().unlock();
}
}
ACTUAL -
void processCachedData() {
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
// Recheck state because another thread might have acquired
// write lock and changed state before we did.
if (!cacheValid) {
data = ...
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
rwl.writeLock().unlock(); // Unlock write, still hold read
}
use(data);
rwl.readLock().unlock();
}
URL OF FAULTY DOCUMENTATION :
file:///C:/Java/jdk1.6.0/docs/api/java/util/concurrent/locks/ReentrantReadWriteLock.html