public class FastThreadLocalThread extends Thread {
private InternalThreadLocalMap threadLocalMap;
public FastThreadLocalThread() { }
public FastThreadLocalThread(Runnable target) {
super(target);
}
public FastThreadLocalThread(ThreadGroup group, Runnable target) {
super(group, target);
}
public FastThreadLocalThread(String name) {
super(name);
}
public FastThreadLocalThread(ThreadGroup group, String name) {
super(group, name);
}
public FastThreadLocalThread(Runnable target, String name) {
super(target, name);
}
public FastThreadLocalThread(ThreadGroup group, Runnable target, String name) {
super(group, target, name);
}
public FastThreadLocalThread(ThreadGroup group, Runnable target, String name, long stackSize) {
super(group, target, name, stackSize);
}
/**
* Returns the internal data structure that keeps the thread-local variables bound to this thread.
* Note that this method is for internal use only, and thus is subject to change at any time.
*/
public final InternalThreadLocalMap threadLocalMap() {
return threadLocalMap;
}
/**
* Sets the internal data structure that keeps the thread-local variables bound to this thread.
* Note that this method is for internal use only, and thus is subject to change at any time.
*/
public final void setThreadLocalMap(InternalThreadLocalMap threadLocalMap) {
this.threadLocalMap = threadLocalMap;
}
}
Netty专门提供一个FastThreadLocalThread,继承了JDK的Thread,内部也有个InternalThreadLocalMap实例变量,并暴露了这个变量的getter/setter方法。
JDK中的ThreadLocalMap中的数组存放的是Entrty,key为ThreadLocal,value为真正保存的变量,而InternalThreadLocalMap中的数组里面的数据就是真正保存的变量值。
public class FastThreadLocal {
private static final int variablesToRemoveIndex = InternalThreadLocalMap.nextVariableIndex();
private final int index;
public FastThreadLocal() {
index = InternalThreadLocalMap.nextVariableIndex();
}
//……
}
JDK的ThreadLocal中将threadLocalHashCode放在了ThreadLocal类中,然后再拿这个值通过计算去定位ThreadLocalMap中的槽,而Netty的FastThreadLocal直接直接保存index,该index是通过InternalThreadLocalMap的静态方法获取的,该值是一个递增的值,也就是说不同的线程,在同一个FastThreadLocal中保存的变量值,在其实例变量InternalThreadLocalMap中的槽都是一样的。
public class Test {
static FastThreadLocal threadLocal = new FastThreadLocal(){
@Override
protected String initialValue() throws Exception {
return "zero";
}
};
public static void main(String[] args) {
FastThreadLocalThread thread0 = new FastThreadLocalThread(new Runnable() {
@Override
public void run() {
System.out.println(threadLocal.get());
}
});
FastThreadLocalThread thread1 = new FastThreadLocalThread(new Runnable() {
@Override
public void run() {
System.out.println(threadLocal.get());
}
});
thread0.start();
thread1.start();
}
}
上面的例子,线程私有的String变量,在线程的实例变量threadLocalMap里的数组,存放的位置下标都是1。由于InternalThreadLocal的index会递增,因此InternalThreadLocal实例再多的话也只会扩容,而不会发生Hash冲突。