Recently I learned about the existence StampedLock
?
https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/locks/StampedLock.html I realized that It is improved ReentrantReadWriteLock with some differernces:
Also I read examples frpm javadoc but I don't understant that code:
class Point {
private double x, y;
private final StampedLock sl = new StampedLock();
// a read-only method
// upgrade from optimistic read to read lock
double distanceFromOrigin() {
long stamp = sl.tryOptimisticRead();
try {
retryHoldingLock: for (;; stamp = sl.readLock()) {
if (stamp == 0L)
continue retryHoldingLock;
// possibly racy reads
double currentX = x;
double currentY = y;
if (!sl.validate(stamp))
continue retryHoldingLock;
return Math.hypot(currentX, currentY);
}
} finally {
if (StampedLock.isReadLockStamp(stamp))
sl.unlockRead(stamp);
}
}
}
What does it mean possibly racy reads
? [ANSWERRED IN COMMENTS]
Is it a problem if another thread reads x
or y
? [ANSWERRED IN COMMENTS]
why do we execute tryOptimisticRead first and readLock in the for loop in case of tryOptimisticRead failure? what the logic?
Why do we have if (StampedLock.isReadLockStamp(stamp))
inside finally block vbefore unlock ?
why do we execute tryOptimisticRead first and readLock in the for loop in case of tryOptimisticRead failure? what the logic?
A best case scenario is for us to to be able to read x
and y
without having to acquire a lock. That doesn't mean we don't establish a happens-before relationship, it just means we don't need to invoke a possible blocking action.
tryOptimisticRead
returns us a stamp value. This volatile
read of internal state establishes that anything written prior to the volatile write of this stamped value will be visible after a subsequent read. That means, if the stamped value returned in tryOptimisticRead
doesn't change while you read x
and y
, then another write did not occur and we have the most up to date values. If the stamped value does change, however, all bets are off and you need to protect yourself explained below.
It's possible, and, depending on your use case, likely, that x
and y
will change at some point throughout your execution of distanceFromOrigin
. If x
and y
change, and maybe change often, you're going to want to eventually succeed.
The readLock
is the program's way of saying "Ok, I give up, let's just read it in a blocking fashion". In theory, you can write your code to tryOptimisticRead
a few times before eventually invoking readLock
, but you're going to want to give yourself an out in case x
and y
are updated constantly.
Why do we have if (StampedLock.isReadLockStamp(stamp)) inside finally block vbefore unlock ?
If readLock
is invoked, you will have to release it prior to exiting so that subsequent writeLock
can acquire the lock. If you succeed in tryOptimisticRead
you will not have to release a readLock
as you never needed to acquire it in the first place.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With