* forgot my footnote -- Marcin pointed out that there is a null being set somewhere in JI code. I haven't had a chance to research it, but it's definitely not intentional.
-Bill On 10/5/07, Bill Dortch <[EMAIL PROTECTED]> wrote: > > > > On 10/5/07, MenTaLguY <[EMAIL PROTECTED]> wrote: > > > > There is a data race here: > > > > // external volatile value initialization intended to obviate the need > > for > > // readValueUnderLock technique used in ConcurrentHashMap. may be a > > little > > // slower, but better to pay a price on first write rather than all > > reads. > > e = new VariableTableEntry(hash, name.intern(), table[index]); > > e.value = value; > > table[index] = e; > > variableTableSize = potentialNewSize; > > variableTable = table; // write-volatile > > > > Since table[index] is not a volatile location, other threads are allowed > > > > to see the write to table[index] before the write to e.value; it is > > possible to get "phantom nulls". The fact that e.value is a volatile > > location means only that reads of e.value will see all writes up to and > > including a write to it; it doesn't enforce the non-visibility of > > subsequent writes. Whether the write to e.value happens in or out of > > the constructor doesn't really matter. > > > > I've questioned whether this was actually safe (hence the call-out in the > code), but at least one thread I read in the JMM mailing list archives > seemed to suggest that a compiler would not reorder the write to > table[index] WRT the write to e.value, which is the issue. It did seem to > me that this was not much different than setting the field in the > constructor. > > In any case, the readValueUnderLock technique isn't too terribly painful; > we don't actually (intentionally*) store any null values right now (though > that could change in a lightweight implementation in which null represented > Ruby nil), and, as noted in a comment in ConcurrentHashMap, no compiler is > currently (at the time the comment was written, anyway) known to reorder > object initialization WRT an array store of that object, so the > readValueUnderLock method is unlikely ever to be called. The added > overhead, therefore, is just a DUP, ASTORE, IFNULL, ALOAD sequence for each > read. (Still, a nanosecond here, a nanosecond there, before you know it > you're talking real time...) > > Anyway, I'm glad you brought this up, I was hoping someone would either > confirm or contradict the assumptions of this approach. > > -Bill >