JDK8: StampedLock: A possible SequenceLock replacement

Quite some time back I wrote about SequenceLock – a new kind of lock, due for release, in JDK8 where each lock acquisition or release advanced a sequence number. Two days ago, however, Doug Lea has reported that, for a variety of reasons, this API may be “less useful than anticipated”. Instead he has proposed a replacement API called StampedLock and requested feedback on it.

Here I reproduce example usage of both APIs for for easy comparison by the reader.

SequenceLock sample usage

[java]
class Point {
private volatile double x, y;
private final SequenceLock sl = new SequenceLock();

// A read-only method
double distanceFromOriginV1() {
double currentX, currentY;
long seq;
do {
seq = sl.awaitAvailability();
currentX = x;
currentY = y;
} while (sl.getSequence() != seq); // retry if sequence changed
return Math.sqrt(currentX * currentX + currentY * currentY);
}

// an exclusively locked method
void move(double deltaX, double deltaY) {
sl.lock();
try {
x += deltaX;
y += deltaY;
} finally {
sl.unlock();
}
}

// Uses bounded retries before locking
double distanceFromOriginV2() {
double currentX, currentY;
long seq;
int retries = RETRIES_BEFORE_LOCKING; // for example 8
try {
do {
if (–retries < 0)
sl.lock();
seq = sl.awaitAvailability();
currentX = x;
currentY = y;
} while (sl.getSequence() != seq);
} finally {
if (retries < 0)
sl.unlock();
}
return Math.sqrt(currentX * currentX + currentY * currentY);
}
}
[/java]

StampedLock sample usage

[java]
class Point {
private int x, y;
private final StampedLock lock = new StampedLock();

public int magnitude() { // a read-only method
long stamp = lock.beginObserving();
try {
int currentX = x;
int currentY = y;
} finally {
if (!lock.validate(stamp)) {
stamp = lock.lockForReading();
try {
currentX = x;
currentY = y;
} finally {
lock.unlock(stamp);
}
}
return currentX * currentX + currentY * currentY;
}
}

public void move(int deltaX, int deltaY) { // a write-locked method
long stamp = lock.lockForWriting();
try {
x += deltaX;
y += deltaY;
} finally {
lock.unlock(stamp);
}
}
}
[/java]

There are two primary differences that I can see. First of all – in SequenceLock the read only method has an element of indefinite retry without lock acquisition. In StampedLock, however, the retry element is replaced with lock acquisition which would perform better under a lot of writes. Secondly, the single undifferentiated lock in SequenceLock is replaced with a differentiated read and write lock. The latter feature makes this class another alternative to the existing class: ReentrantReadWriteLock that Doug Lea describes as “cheaper but more restricted”. It will be fascinating to watch the progression of this API over time.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s