On 03/24/2014 06:52 PM, Martin Buchholz wrote:



On Wed, Mar 12, 2014 at 1:45 AM, Peter Levart <peter.lev...@gmail.com <mailto:peter.lev...@gmail.com>> wrote:


    What would the following cost?


        private transient String stringCache;

        public String toString() {
            String sc = stringCache;
            if (sc == null) {
                sc = (String) U.getObjectVolatile(this,
    STRING_CACHE_OFFSET);
                if (sc == null) {
                    sc = layoutChars(true);
                    if (!U.compareAndSwapObject(this,
    STRING_CACHE_OFFSET, null, sc)) {
                        sc = (String) U.getObjectVolatile(this,
    STRING_CACHE_OFFSET);
                    }
                }
            }
            return sc;
        }


I feel I'm missing something. If read -> volatile read -> CAS works, then why wouldn't read -> CAS work and be slightly preferable, because "races are unlikely"?

public String toString() {
      String sc = stringCache;
      if (sc == null) {
          sc = layoutChars(true);
if (!U.compareAndSwapObject(this, STRING_CACHE_OFFSET, null, sc)) { sc = (String) U.getObjectVolatile(this, STRING_CACHE_OFFSET);
          }
      }
      return sc;
  }

...yeah, I thought about that too. In any case, the overhead of volatile re-read is negligible in this case, since it happens on slow-path and it might reduce the chance of superfluos calls to layoutChars.

Regards, Peter

Reply via email to