public override V Get() // serialize access { lock (this) { // re-check Supplier <V> supplier = ValuesMap[SubKey]; if (supplier != this) { // something changed while we were waiting: // might be that we were replaced by a CacheValue // or were removed because of failure -> // return null to signal WeakCache.get() to retry // the loop return(null); } // else still us (supplier == this) // create new value V value = null; try { value = Objects.RequireNonNull(outerInstance.ValueFactory.Apply(Key, Parameter)); } finally { if (value == null) // remove us on failure { ValuesMap.Remove(SubKey, this); } } // the only path to reach here is with non-null value Debug.Assert(value != null); // wrap value with CacheValue (WeakReference) CacheValue <V> cacheValue = new CacheValue <V>(value); // try replacing us with CacheValue (this should always succeed) if (ValuesMap.Replace(SubKey, this, cacheValue)) { // put also in reverseMap outerInstance.ReverseMap[cacheValue] = true; } else { throw new AssertionError("Should not reach here"); } // successfully replaced us with new CacheValue -> return the value // wrapped by it return(value); } }