月是一轮明镜,晶莹剔透,代表着一张白纸(啥也不懂)
央是一片海洋,海乃百川,代表着一块海绵(吸纳万物)
泽是一柄利剑,千锤百炼,代表着千百锤炼(输入输出)
月央泽,学习的一种过程,从白纸->吸收各种知识->不断输入输出变成自己的内容
希望大家一起坚持这个过程,也同样希望大家最终都能从零到零,把知识从薄变厚,再由厚变薄!
直接看源码注释(我的翻译可能不太准,如果道友们有更棒的理解,可以留言或者私信)
二.成员变量:
//所有 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 Entry extends 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;
Entry e = 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一下,看未来这东西有啥用....



