Gili
Gili

Reputation: 90150

Does StampedLock.writeLock() release a read-lock held by the current thread?

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 call writeLock() 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

Answers (1)

Gili
Gili

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

Related Questions