Пример #1
0
            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);
                }
            }