月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂)
央是一片海洋,海乃百川,代表着一块海绵(吸纳万物)
泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出)
月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容
希望大家一起坚持这个过程,也同样希望大家最终都能从零到零,把知识从薄变厚,再由厚变薄!
直接看源码注释(我的翻译可能不太准,如果道友们有更棒的理解,可以留言或者私信)
二.成员变量://所有 Class 实例使用的初始、单元素、空缓存。绝对不能填满 private static final Entry>[] EMPTY_CACHE = { null }; //用于访问 Class.classValueMap.cacheArray 的内部哈希码。 final int hashCodeForCache = nextHashCode.getAndAdd(HASH_INCREMENT) & HASH_MASK; //hashCodeForCache 的值流。请参阅 ThreadLocal 中的类似结构 private static final AtomicInteger nextHashCode = new AtomicInteger(); //适用于 2 的幂表。请参阅 ThreadLocal 中的类似结构 private static final int HASH_INCREMENT = 0x61c88647; //将哈希码屏蔽为正数但不要太大,以防止回绕。 static final int HASH_MASK = (-1 >>> 2); final Identity identity = new Identity(); //避免死锁的私有对象 private static final Object CRITICAL_SECTION = new Object(); //判断当前对象的版本 private volatile Version三.内部类:version = new Version<>(this);
Identity
static class Identity { }
Version
static class Version{ private final ClassValue classValue; private final Entry promise = new Entry<>(this); Version(ClassValue classValue) { this.classValue = classValue; } ClassValue classValue() { return classValue; } Entry promise() { return promise; } boolean isLive() { return classValue.version() == this; } }
Entry
static class Entryextends WeakReference > { //通常是 T 型,但有时 (Entry)this final Object value; // usually of type T, but sometimes (Entry)this Entry(Version version, T value) { super(version); //对于常规条目,值的类型为 T this.value = value; // for a regular entry, value is of type T } private void assertNotPromise() { assert(!isPromise()); } //promise状态 Entry(Version version) { super(version); this.value = this; // for a promise, value is not of type T, but Entry! } //取值。此条目不能是Promise @SuppressWarnings("unchecked") // if !isPromise, type is T T value() { assertNotPromise(); return (T) value; } boolean isPromise() { return value == this; } Version version() { return get(); } ClassValue classValueOrNull() { Version v = version(); return (v == null) ? null : v.classValue(); } boolean isLive() { Version v = version(); if (v == null) return false; if (v.isLive()) return true; clear(); return false; } Entry refreshVersion(Version v2) { assertNotPromise(); @SuppressWarnings("unchecked") // if !isPromise, type is T Entry e2 = new Entry<>(v2, (T) value); clear(); // value = null -- caller must drop return e2; } //dead状态 static final Entry> DEAD_ENTRY = new Entry<>(null, null); }
ClassValueMap
static class ClassValueMap extends WeakHashMap四.构造方法:> { private final Class> type; private Entry>[] cacheArray; private int cacheLoad, cacheLoadLimit; private static final int INITIAL_ENTRIES = 32; ClassValueMap(Class> type) { this.type = type; sizeCache(INITIAL_ENTRIES); } Entry>[] getCache() { return cacheArray; } //发起查询。如果还没有值,则存储promise(占位符) synchronized Entry startEntry(ClassValue classValue) { @SuppressWarnings("unchecked") // one map has entries for all value types Entry e = (Entry ) get(classValue.identity); Version v = classValue.version(); if (e == null) { e = v.promise(); //promise的存在意味着 v 的值正在等待。最终,finishEntry 将覆盖promise put(classValue.identity, e); // Note that the promise is never entered into the cache! //请注意,promise永远不会进入缓存 return e; } else if (e.isPromise()) { // Somebody else has asked the same question. // Let the races begin! if (e.version() != v) { e = v.promise(); put(classValue.identity, e); } return e; } else { // there is already a completed entry here; report it //这里已经有一个完整的条目;举报 if (e.version() != v) { //这里有一个陈旧但有效的条目;让它再次新鲜。 // 一旦一个条目在哈希表中,我们就不关心它的版本是什么 e = e.refreshVersion(v); put(classValue.identity, e); } // Add to the cache, to enable the fast path, next time. //添加到缓存中,下次以启用快速路径, checkCacheLoad(); addToCache(classValue, e); return e; } } synchronized Entry finishEntry(ClassValue classValue, Entry e) { @SuppressWarnings("unchecked") // one map has entries for all value types Entry e0 = (Entry ) get(classValue.identity); if (e == e0) { // We can get here during exception processing, unwinding from computevalue. assert(e.isPromise()); remove(classValue.identity); return null; } else if (e0 != null && e0.isPromise() && e0.version() == e.version()) { // If e0 matches the intended entry, there has not been a remove call // between the previous startEntry and now. So now overwrite e0. Version v = classValue.version(); if (e.version() != v) e = e.refreshVersion(v); put(classValue.identity, e); // Add to the cache, to enable the fast path, next time. checkCacheLoad(); addToCache(classValue, e); return e; } else { // Some sort of mismatch; caller must try again. return null; } } synchronized void removeEntry(ClassValue> classValue) { Entry> e = remove(classValue.identity); if (e == null) { // Uninitialized, and no pending calls to computevalue. No change. } else if (e.isPromise()) { // State is uninitialized, with a pending call to finishEntry. // Since remove is a no-op in such a state, keep the promise // by putting it back into the map. put(classValue.identity, e); } else { // In an initialized state. Bump forward, and de-initialize. classValue.bumpVersion(); // Make all cache elements for this guy go stale. removeStaleEntries(classValue); } } synchronized void changeEntry(ClassValue classValue, T value) { @SuppressWarnings("unchecked") // one map has entries for all value types Entry e0 = (Entry ) get(classValue.identity); Version version = classValue.version(); if (e0 != null) { if (e0.version() == version && e0.value() == value) // no value change => no version change needed return; classValue.bumpVersion(); removeStaleEntries(classValue); } Entry e = makeEntry(version, value); put(classValue.identity, e); // Add to the cache, to enable the fast path, next time. checkCacheLoad(); addToCache(classValue, e); } static Entry> loadFromCache(Entry>[] cache, int i) { // non-racing cache.length : constant // racing cache[i & (mask)] : null <=> Entry return cache[i & (cache.length-1)]; // invariant: returned value is null or well-constructed (ready to match) } static Entry probeHomeLocation(Entry>[] cache, ClassValue classValue) { return classValue.castEntry(loadFromCache(cache, classValue.hashCodeForCache)); } static Entry probeBackupLocations(Entry>[] cache, ClassValue classValue) { if (PROBE_LIMIT <= 0) return null; // Probe the cache carefully, in a range of slots. int mask = (cache.length-1); int home = (classValue.hashCodeForCache & mask); Entry> e2 = cache[home]; // victim, if we find the real guy if (e2 == null) { return null; // if nobody is at home, no need to search nearby } // assume !classValue.match(e2), but do not assert, because of races int pos2 = -1; for (int i = home + 1; i < home + PROBE_LIMIT; i++) { Entry> e = cache[i & mask]; if (e == null) { break; // only search within non-null runs } if (classValue.match(e)) { // relocate colliding entry e2 (from cache[home]) to first empty slot cache[home] = e; if (pos2 >= 0) { cache[i & mask] = Entry.DEAD_ENTRY; } else { pos2 = i; } cache[pos2 & mask] = ((entryDislocation(cache, pos2, e2) < PROBE_LIMIT) ? e2 // put e2 here if it fits : Entry.DEAD_ENTRY); return classValue.castEntry(e); } // Remember first empty slot, if any: if (!e.isLive() && pos2 < 0) pos2 = i; } return null; } //e 离位多远? private static int entryDislocation(Entry>[] cache, int pos, Entry> e) { ClassValue> cv = e.classValueOrNull(); if (cv == null) return 0; // entry is not live! int mask = (cache.length-1); return (pos - cv.hashCodeForCache) & mask; } private void sizeCache(int length) { assert((length & (length-1)) == 0); // must be power of 2 cacheLoad = 0; cacheLoadLimit = (int) ((double) length * CACHE_LOAD_LIMIT / 100); cacheArray = new Entry>[length]; } //如果可能,请确保缓存负载保持在其限制以下 private void checkCacheLoad() { if (cacheLoad >= cacheLoadLimit) { reduceCacheLoad(); } } private void reduceCacheLoad() { removeStaleEntries(); if (cacheLoad < cacheLoadLimit) return; // win Entry>[] oldCache = getCache(); if (oldCache.length > HASH_MASK) return; // lose sizeCache(oldCache.length * 2); for (Entry> e : oldCache) { if (e != null && e.isLive()) { addToCache(e); } } } private void removeStaleEntries(Entry>[] cache, int begin, int count) { if (PROBE_LIMIT <= 0) return; int mask = (cache.length-1); int removed = 0; for (int i = begin; i < begin + count; i++) { Entry> e = cache[i & mask]; if (e == null || e.isLive()) continue; // skip null and live entries Entry> replacement = null; if (PROBE_LIMIT > 1) { // avoid breaking up a non-null run //避免中断非空运行 replacement = findReplacement(cache, i); } cache[i & mask] = replacement; if (replacement == null) removed += 1; } cacheLoad = Math.max(0, cacheLoad - removed); } private Entry> findReplacement(Entry>[] cache, int home1) { Entry> replacement = null; int haveReplacement = -1, replacementPos = 0; int mask = (cache.length-1); for (int i2 = home1 + 1; i2 < home1 + PROBE_LIMIT; i2++) { Entry> e2 = cache[i2 & mask]; if (e2 == null) break; // End of non-null run. if (!e2.isLive()) continue; // Doomed anyway. int dis2 = entryDislocation(cache, i2, e2); if (dis2 == 0) continue; // e2 already optimally placed int home2 = i2 - dis2; if (home2 <= home1) { // e2 can replace entry at cache[home1] if (home2 == home1) { // Put e2 exactly where he belongs. haveReplacement = 1; replacementPos = i2; replacement = e2; } else if (haveReplacement <= 0) { haveReplacement = 0; replacementPos = i2; replacement = e2; } // And keep going, so we can favor larger dislocations. } } if (haveReplacement >= 0) { if (cache[(replacementPos+1) & mask] != null) { // Be conservative, to avoid breaking up a non-null run. cache[replacementPos & mask] = (Entry>) Entry.DEAD_ENTRY; } else { cache[replacementPos & mask] = null; cacheLoad -= 1; } } return replacement; } //删除 classValue 附近范围内的陈旧条目 private void removeStaleEntries(ClassValue> classValue) { removeStaleEntries(getCache(), classValue.hashCodeForCache, PROBE_LIMIT); } //删除所有陈旧条目,无处不在 private void removeStaleEntries() { Entry>[] cache = getCache(); removeStaleEntries(cache, 0, cache.length + PROBE_LIMIT - 1); } //将给定条目添加到缓存中,在其主位置,除非它已过期 private void addToCache(Entry e) { ClassValue classValue = e.classValueOrNull(); if (classValue != null) addToCache(classValue, e); } //将给定的条目添加到缓存中,在其主位置 private void addToCache(ClassValue classValue, Entry e) { if (PROBE_LIMIT <= 0) return; // do not fill cache // Add e to the cache. Entry>[] cache = getCache(); int mask = (cache.length-1); int home = classValue.hashCodeForCache & mask; Entry> e2 = placeInCache(cache, home, e, false); if (e2 == null) return; // done if (PROBE_LIMIT > 1) { // try to move e2 somewhere else in his probe range int dis2 = entryDislocation(cache, home, e2); int home2 = home - dis2; for (int i2 = home2; i2 < home2 + PROBE_LIMIT; i2++) { if (placeInCache(cache, i2 & mask, e2, true) == null) { return; } } } // Note: At this point, e2 is just dropped from the cache. } private Entry> placeInCache(Entry>[] cache, int pos, Entry> e, boolean gently) { Entry> e2 = overwrittenEntry(cache[pos]); if (gently && e2 != null) { // do not overwrite a live entry return e; } else { cache[pos] = e; return e2; } } private Entry overwrittenEntry(Entry e2) { if (e2 == null) cacheLoad += 1; else if (e2.isLive()) return e2; return null; } //调整大小前缓存的加载百分比 private static final int CACHE_LOAD_LIMIT = 67; // 0..100 //尝试的最大探测数 private static final int PROBE_LIMIT = 6; // 1.. }
protected ClassValue() { }五.内部方法:
computevalue
protected abstract T computevalue(Class> type);
get()
public T get(Class> type) { Entry>[] cache; Entrye = probeHomeLocation(cache = getCacheCarefully(type), this); //当前值 <=> 来自当前缓存或陈旧缓存的陈旧值 //e 为 null 或具有可读 Entry.version 和 Entry.value 的条目 if (match(e)) return e.value(); //快速路径可能因以下任何原因而失败: // 1. 尚未计算任何条目 // 2. 哈希码冲突(减少 mod cache.length 之前或之后) // 3. 条目已被删除(在此类型或其他类型上) // 4 . GC 以某种方式设法删除了 e.version 并清除了引用 return getFromBackup(cache, type); }
remove()
public void remove(Class> type) { ClassValueMap map = getMap(type); map.removeEntry(this); }
match
//检查 e 是否为非空、是否与此 ClassValue 匹配且是否有效 boolean match(Entry> e) { return (e != null && e.get() == this.version); }六.总结:
mark一下,看未来这东西有啥用....
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)