为ThreadLocal定制的ThreadLocalMap(二)

2014-11-24 03:19:40 · 作者: · 浏览: 1
return;

}

if (k == null) {

replaceStaleEntry(key, value, i);

return;

}

}

tab = new Entry(key, value);

int sz = ++size;

if (!cleanSomeSlots(i, sz) && sz >= threshold)

rehash();

}

private void remove(Key key) {

Entry[] tab = table;

int len = tab.length;

int i = key.hashCode & (len-1);

for (Entry e = tab;

e != null;

e = tab[i = nextIndex(i, len)]) {

if (e.get() == key) {

e.clear();

expungeStaleEntry(i);

return;

}

}

}

private void replaceStaleEntry(Key key, Object value,

int staleSlot) {

Entry[] tab = table;

int len = tab.length;

Entry e;

int slotToExpunge = staleSlot;

for (int i = prevIndex(staleSlot, len);

(e = tab) != null;

i = prevIndex(i, len))

if (e.get() == null)

slotToExpunge = i;

for (int i = nextIndex(staleSlot, len);

(e = tab) != null;

i = nextIndex(i, len)) {

Key k = e.get();

if (k == key) {

e.value = value;

tab = tab[staleSlot];

tab[staleSlot] = e;

// Start expunge at preceding stale entry if it exists

if (slotToExpunge == staleSlot)

slotToExpunge = i;

cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);

return;

}

if (k == null && slotToExpunge == staleSlot)

slotToExpunge = i;

}

// If key not found, put new entry in stale slot

tab[staleSlot].value = null;

tab[staleSlot] = new Entry(key, value);

// If there are any other stale entries in run, expunge them

if (slotToExpunge != staleSlot)

cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);

}

/**擦除staleSlot的Entry。

*调整所有不在哈希映射位置的value的位置,让它尽量在哈希映射的位置

*/

private int expungeStaleEntry(int staleSlot) {

Entry[] tab = table;

int len = tab.length;

tab[staleSlot].value = null;

tab[staleSlot] = null;

size--;

// Rehash until we encounter null

Entry e;

int i;

for (i = nextIndex(staleSlot, len);

(e = tab) != null;

i = nextIndex(i, len)) {

Key k = e.get();

if (k == null) {

e.value = null;

tab = null;

size--;

} else {

int h = k.hashCode & (len - 1);

if (h != i) {

tab = null;

// Unlike Knuth 6.4 Algorithm R, we must scan until

// null because multiple entries could have been stale.

while (tab[h] != null)