Reputation: 90150
http://winterbe.com/posts/2015/04/30/java8-concurrency-tutorial-synchronized-locks-examples/ contains this code:
StampedLock lock = new StampedLock();
long stamp = lock.readLock();
try {
if (count == 0) {
stamp = lock.tryConvertToWriteLock(stamp);
if (stamp == 0L) {
System.out.println("Could not convert to write lock");
stamp = lock.writeLock();
}
count = 23;
}
System.out.println(count);
} finally {
lock.unlock(stamp);
}
The author writes:
Calling
tryConvertToWriteLock()
doesn't block but may return a zero stamp indicating that no write lock is currently available. In that case we callwriteLock()
to block the current thread until a write lock is available.
Regarding the case where tryConvertToWriteLock()
fails, did I miss something or is the author acquiring a read-lock, followed by a write-lock, and never releasing the read-lock?
Further, won't lock.writeLock()
deadlock waiting for the current thread to release its read-lock?
Upvotes: 7
Views: 985
Reputation: 90150
I believe the code sample provided by the article is buggy. According to https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/locks/StampedLock.html
Like Semaphore, but unlike most Lock implementations, StampedLocks have no notion of ownership. Locks acquired in one thread can be released or converted in another.
Further, they provide the following sample code:
void moveIfAtOrigin(double newX, double newY) { // upgrade
// Could instead start with optimistic, not read mode
long stamp = sl.readLock();
try {
while (x == 0.0 && y == 0.0) {
long ws = sl.tryConvertToWriteLock(stamp);
if (ws != 0L) {
stamp = ws;
x = newX;
y = newY;
break;
}
else {
sl.unlockRead(stamp);
stamp = sl.writeLock();
}
}
} finally {
sl.unlock(stamp);
}
}
Notice how they release the read-lock before acquiring a write-lock.
Upvotes: 6