http://blog.csdn.net/lclansefengbao/article/details/38143411java
- package java.lang;
- import java.lang.ref.*;
- import java.util.concurrent.atomic.AtomicInteger;
-
- public class ThreadLocal<T> {
-
- private final int threadLocalHashCode = nextHashCode();
-
- private static AtomicInteger nextHashCode =
- new AtomicInteger();
-
- private static final int HASH_INCREMENT = 0x61c88647;
-
- private static int nextHashCode() {
- return nextHashCode.getAndAdd(HASH_INCREMENT);
- }
-
- protected T initialValue() {
- return null;
- }
-
- public ThreadLocal() {
- }
-
-
- public T get() {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null) {
- ThreadLocalMap.Entry e = map.getEntry(this);
- if (e != null)
- return (T)e.value;
- }
- return setInitialValue();
-
- }
-
-
- private T setInitialValue() {
- T value = initialValue();
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null)
- map.set(this, value);
- else
- createMap(t, value);
- return value;
- }
-
- public void set(T value) {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null)
- map.set(this, value);
- else
- createMap(t, value);
- }
-
- public void remove() {
- ThreadLocalMap m = getMap(Thread.currentThread());
- if (m != null)
- m.remove(this);
- }
-
-
- ThreadLocalMap getMap(Thread t) {
- return t.threadLocals;
- }
-
-
- void createMap(Thread t, T firstValue) {
- t.threadLocals = new ThreadLocalMap(this, firstValue);
- }
-
-
- static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
- return new ThreadLocalMap(parentMap);
- }
-
-
- T childValue(T parentValue) {
- throw new UnsupportedOperationException();
- }
-
- static class ThreadLocalMap {
-
- static class Entry extends WeakReference<ThreadLocal> {
-
- Object value;
-
- Entry(ThreadLocal k, Object v) {
- super(k);
- value = v;
- }
- }
-
- private static final int INITIAL_CAPACITY = 16;
-
-
- private Entry[] table;
-
- private int size = 0;
-
- private int threshold;
-
- private void setThreshold(int len) {
- threshold = len * 2 / 3;
- }
-
- private static int nextIndex(int i, int len) {
- return ((i + 1 < len) ? i + 1 : 0);
- }
-
- private static int prevIndex(int i, int len) {
- return ((i - 1 >= 0) ? i - 1 : len - 1);
- }
-
- ThreadLocalMap(ThreadLocal firstKey, Object firstValue) {
- table = new Entry[INITIAL_CAPACITY];
- int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
- table[i] = new Entry(firstKey, firstValue);
- size = 1;
- setThreshold(INITIAL_CAPACITY);
- }
-
- private ThreadLocalMap(ThreadLocalMap parentMap) {
- Entry[] parentTable = parentMap.table;
- int len = parentTable.length;
- setThreshold(len);
- table = new Entry[len];
-
- for (int j = 0; j < len; j++) {
- Entry e = parentTable[j];
- if (e != null) {
- ThreadLocal key = e.get();
- if (key != null) {
- Object value = key.childValue(e.value);
- Entry c = new Entry(key, value);
- int h = key.threadLocalHashCode & (len - 1);
- while (table[h] != null)
- h = nextIndex(h, len);
- table[h] = c;
- size++;
- }
- }
- }
- }
-
- private Entry getEntry(ThreadLocal key) {
- int i = key.threadLocalHashCode & (table.length - 1);
- Entry e = table[i];
- if (e != null && e.get() == key)
- return e;
- else
- return getEntryAfterMiss(key, i, e);
- }
-
-
- private Entry getEntryAfterMiss(ThreadLocal key, int i, Entry e) {
- Entry[] tab = table;
- int len = tab.length;
-
- while (e != null) {
- ThreadLocal k = e.get();
- if (k == key)
- return e;
- if (k == null)
- expungeStaleEntry(i);
- else
- i = nextIndex(i, len);
- e = tab[i];
- }
- return null;
- }
-
- private void set(ThreadLocal key, Object value) {
-
-
-
-
-
-
- Entry[] tab = table;
- int len = tab.length;
- int i = key.threadLocalHashCode & (len-1);
-
- for (Entry e = tab[i];
- e != null;
- e = tab[i = nextIndex(i, len)]) {
- ThreadLocal k = e.get();
-
- if (k == key) {
- e.value = value;
- return;
- }
-
- if (k == null) {
- replaceStaleEntry(key, value, i);
- return;
- }
- }
-
- tab[i] = new Entry(key, value);
- int sz = ++size;
- if (!cleanSomeSlots(i, sz) && sz >= threshold)
- rehash();
- }
-
- private void remove(ThreadLocal key) {
- Entry[] tab = table;
- int len = tab.length;
- int i = key.threadLocalHashCode & (len-1);
- for (Entry e = tab[i];
- e != null;
- e = tab[i = nextIndex(i, len)]) {
- if (e.get() == key) {
- e.clear();
- expungeStaleEntry(i);
- return;
- }
- }
- }
-
- private void replaceStaleEntry(ThreadLocal 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[i]) != null;
- i = prevIndex(i, len))
- if (e.get() == null)
- slotToExpunge = i;
-
-
-
- for (int i = nextIndex(staleSlot, len);
- (e = tab[i]) != null;
- i = nextIndex(i, len)) {
- ThreadLocal k = e.get();
-
-
-
-
-
-
- if (k == key) {
- e.value = value;
-
- tab[i] = tab[staleSlot];
- tab[staleSlot] = e;
-
-
- if (slotToExpunge == staleSlot)
- slotToExpunge = i;
- cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
- return;
- }
-
-
-
-
- if (k == null && slotToExpunge == staleSlot)
- slotToExpunge = i;
- }
-
-
- tab[staleSlot].value = null;
- tab[staleSlot] = new Entry(key, value);
-
-
- if (slotToExpunge != staleSlot)
- cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
- }
-
-
- private int expungeStaleEntry(int staleSlot) {
- Entry[] tab = table;
- int len = tab.length;
-
-
- tab[staleSlot].value = null;
- tab[staleSlot] = null;
- size--;
-
-
- Entry e;
- int i;
- for (i = nextIndex(staleSlot, len);
- (e = tab[i]) != null;
- i = nextIndex(i, len)) {
- ThreadLocal k = e.get();
- if (k == null) {
- e.value = null;
- tab[i] = null;
- size--;
- } else {
- int h = k.threadLocalHashCode & (len - 1);
- if (h != i) {
- tab[i] = null;
-
-
-
- while (tab[h] != null)
- h = nextIndex(h, len);
- tab[h] = e;
- }
- }
- }
- return i;
- }
-
- private boolean cleanSomeSlots(int i, int n) {
- boolean removed = false;
- Entry[] tab = table;
- int len = tab.length;
- do {
- i = nextIndex(i, len);
- Entry e = tab[i];
- if (e != null && e.get() == null) {
- n = len;
- removed = true;
- i = expungeStaleEntry(i);
- }
- } while ( (n >>>= 1) != 0);
- return removed;
- }
-
- private void rehash() {
- expungeStaleEntries();
-
-
- if (size >= threshold - threshold / 4)
- resize();
- }
-
- private void resize() {
- Entry[] oldTab = table;
- int oldLen = oldTab.length;
- int newLen = oldLen * 2;
- Entry[] newTab = new Entry[newLen];
- int count = 0;
-
- for (int j = 0; j < oldLen; ++j) {
- Entry e = oldTab[j];
- if (e != null) {
- ThreadLocal k = e.get();
- if (k == null) {
- e.value = null;
- } else {
- int h = k.threadLocalHashCode & (newLen - 1);
- while (newTab[h] != null)
- h = nextIndex(h, newLen);
- newTab[h] = e;
- count++;
- }
- }
- }
-
- setThreshold(newLen);
- size = count;
- table = newTab;
- }
-
- private void expungeStaleEntries() {
- Entry[] tab = table;
- int len = tab.length;
- for (int j = 0; j < len; j++) {
- Entry e = tab[j];
- if (e != null && e.get() == null)
- expungeStaleEntry(j);
- }
- }
- }
- }