package ThreadLocalZXF;
import java.lang.ref.WeakReference;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import javax.validation.Valid;
import com.sun.jndi.url.iiopname.iiopnameURLContextFactory;
import ThreadLocalZXF.ThreadLocalZXF.ThreadLocalMap.Entry;
import WeakReferenceZXF.WeakReferenceZXF;
public class ThreadLocalZXF<T> {
private final int threadLocalHashCode = nexHashCode();
private static AtomicInteger nexHashCode = new AtomicInteger();
/**
* def magic_hash(n): ... for i in range(n): ... nextHashCode = i *
* HASH_INCREMENT + HASH_INCREMENT ... print nextHashCode & (n - 1), ...
* print ... >>> magic_hash(16)
*/
private static final int HASH_INCREMENT = 0X61c88647;
private static int nextHashCode() {
return nexHashCode.getAndAdd(HASH_INCREMENT);
}
static class ThreadLocalMap {
static class Entry extends WeakReferenceZXF<ThreadLocalZXF<?>> {
Object value;
public Entry(ThreadLocalZXF<?> k, Object v) {
// threadlocal 弱引用
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(ThreadLocalZXF<?> 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) {
@SuppressWarnings("unchecked")
ThreadLocalZXF<Object> key = (ThreadLocalZXF<Object>) 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(ThreadLocalZXF<?> 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(ThreadLocalZXF<?> key, int i, Entry e) {
Entry[] tab = table;
int len = tab.length;
while (e != null) {
ThreadLocalZXF<?> k = e.get();
if (k == key)
return e;
if (k == null)
// hash冲突
// 存在弱引用被清理,entry=<null,vo>,清理完继续找,至少2个对象有着相同的hash
expungeStaleEntry(i);
else
// hash冲突,
i = nextIndex(i, len);
e = tab[i];
}
return null;
}
private void set(ThreadLocalZXF<?> 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)]) {
ThreadLocalZXF<?> k = e.get();
if (k == key) {
e.value = value;
return;
}
//可能<null,VO> or hash碰撞,导致槽错位
if (k == null) {
replaceStaleEntry(key, value, i);
return;
}
}
tab[i] = new Entry(key, value);
int sz = ++size;
if (!cleanSomeSlots(i, size) && sz >= threshold) {
rehash();
}
}
/**
* 1.向下找,找到k符合,和slot位置的entry交换,如向上向下均未发现任何stale,如果清理该出slot(原k位置)
* 2.向下找,找到k符合,交换slot位置的entry,如向上有stale,则处理向上,否则,向下有stale,则出理向下
* 3.向下也没找到k,直接复制给slot位置
* 4.向下也没找到k,如向上有stale,则处理向上,否则,向下有stale,则出理向下,否则无
* @param key
* @param value
* @param staleSlot
*/
private void replaceStaleEntry(ThreadLocalZXF<?> 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)) {
ThreadLocalZXF<?> k = e.get();
//原来想找的entry在这,赶紧和变质的sb,换回来,下次就可以直接通过hash找到你了
if (k == key) {
e.value = value;
tab[i] = tab[staleSlot];
tab[staleSlot] = e;
//避免误伤友军,staleSlot位置已被填充,此时如果再清expunge,将会清理正确数值
if (slotToExpunge == staleSlot) {
slotToExpunge = i;
}
cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
return;
}
//往上找的没找到stale的,slotToExpunge记录向下找的第一个key==null的位置
if(k==null&&slotToExpunge == staleSlot){
slotToExpunge = i;
}
}
//没找到相匹配的key,在stale槽插入新entry
tab[staleSlot].value = null;
tab[staleSlot] = new Entry(key, value);
//存在其他stale的entry,清理!!!
if(slotToExpunge != staleSlot){
cleanSomeSlots(expungeStaleEntry(slotToExpunge), len);
}
}
}
protected T initialValue() {
return null;
}
/**
* 反回当前线程的初始值
*
* @param supplier
* @return
*/
public static <S> ThreadLocalZXF<S> withInitial(
Supplier<? extends S> supplier) {
return new SuppliedThreadLocal<>(supplier);
}
public T get(){
Thread t = Thread.currentThread();
Threadlo
}
}