Gili
Gili

Reputation: 90150

Is it safe to return object references directly after StampedLock.validate() succeeds?

StampedLock's Javadoc reads:

Optimistic read sections should only read fields and hold them in local variables for later use after validation. Fields read while in optimistic read mode may be wildly inconsistent, so usage applies only when you are familiar enough with data representations to check consistency and/or repeatedly invoke method validate().

I can fully appreciate what could go wrong if I'm returning an object field directly (instead of returning a copy from local variables) when the value in question holds primitive values.

But what happens if my code returns an object reference? Is it any different? Let's discuss a concrete example:

class Test
{
  private final StampedLock = new StampedLock();
  private String name = "John Smith";
  private StringBuilder log = new StringBuilder();

  public void setName(String name)
  {
    long stamp = lock.writeLock();
    try
    {
      this.name = name;
    }
    finally
    {
      lock.unlockWrite(stamp);
    }
  }

  public String getName()
  {
    long stamp = lock.tryOptimisticRead();
    try
    {
      V result = name;
      if (lock.validate(stamp))
        return result;
      stamp = lock.readLock();
      try
      {
        return name;
      }
    }
    catch (RuntimeException e)
    {
      throw e;
    }
    catch (Exception e)
    {
        throw WrappingException.wrap(e);
    }
    finally
    {
        lock.unlockRead(stamp);
    }
  }

  // For brevity, assume that "log" has identical getter/setter implementations
}    

Disregarding the case where StampedLock.validate() returns false, I take note of three things:

  1. name is immutable, but the field that references it may change.
  2. log is mutable and the field that references it may change.
  3. The getter methods return a copy of each respective object reference.

To my understanding:

  1. Whether I return the object reference directly or make a local copy and return that, both operations will be thread-safe in the sense that I'll get back a valid object reference...
  2. The state of immutable fields (such as name) are guaranteed to be safe for the caller to interact with.
  3. The state of mutable fields (such as log) are not guaranteed to be thread-safe. Meaning, the reference I am returning might be valid but it state of the referenced object might be in transition.

Lastly, while the getters might return valid object references, there is no guarantee that Test.name and Test.log still point to the same objects. The second the getter returns, their references may change.

Did I capture all the nuances above, or did I miss anything?

Edit: In retrospect, I guess it's impossible to return the object reference directly since we have to invoke StampedLock.validate() after reading any fields. In the above code, V result = ... is actually creating a local copy prior to returning from the method.)

Upvotes: 1

Views: 43

Answers (0)

Related Questions