On Mar 24 2014, at 12:25 , Martin Buchholz <marti...@google.com> wrote:

> 
> 
> 
> On Mon, Mar 24, 2014 at 11:25 AM, Peter Levart <peter.lev...@gmail.com> wrote:
> 
> 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> 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.
> 
> Hmmm OK.  I still slightly prefer my version, but I can see there is a 
> tradeoff, and the difference is very small.

The other issue here, and why this thread has gone on so long, is that we've 
been trying to establish what the best idiom is (for 2014-????) for this lazy 
initialization situation so that we can reuse it with less thought and review. 
In this case the chances of race are fairly low and the cost of extra 
layoutChars is bearable. In other cases where we are likely to use the same 
idiom this is less likely true. Peter's current implementation has the 
advantage that is the best-right answer for lazy initialization even in the 
contended/expensive case. I look forward to revisiting this again when the new 
JMM primitives are available. :-)

Mike


Reply via email to