/** * A special {@link Thread} that provides fast access to {@link FastThreadLocal} variables. * 一种特殊的{@link Thread},可以快速访问{@link FastThreadLocal}变量。 */ publicclassFastThreadLocalThreadextendsThread{ // This will be set to true if we have a chance to wrap the Runnable. privatefinalboolean cleanupFastThreadLocals;
/** * The internal data structure that stores the thread-local variables for Netty and all {@link FastThreadLocal}s. * Note that this class is for internal use only and is subject to change at any time. Use {@link FastThreadLocal} * unless you know what you are doing. */ publicfinalclassInternalThreadLocalMapextendsUnpaddedInternalThreadLocalMap{ staticfinal ThreadLocal<InternalThreadLocalMap> slowThreadLocalMap = new ThreadLocal<InternalThreadLocalMap>(); staticfinal AtomicInteger nextIndex = new AtomicInteger();
/** Used by {@link FastThreadLocal} */ Object[] indexedVariables; publicstaticfinal Object UNSET = new Object(); publicstatic InternalThreadLocalMap get(){ Thread thread = Thread.currentThread(); if (thread instanceof FastThreadLocalThread) { return fastGet((FastThreadLocalThread) thread); } else { return slowGet(); } }
privatestatic InternalThreadLocalMap slowGet(){ ThreadLocal<InternalThreadLocalMap> slowThreadLocalMap = UnpaddedInternalThreadLocalMap.slowThreadLocalMap; InternalThreadLocalMap ret = slowThreadLocalMap.get(); if (ret == null) { ret = new InternalThreadLocalMap(); slowThreadLocalMap.set(ret); } return ret; }
publicstaticintnextVariableIndex(){ int index = nextIndex.getAndIncrement(); if (index < 0) { nextIndex.decrementAndGet(); thrownew IllegalStateException("too many thread-local indexed variables"); } return index; } /** * @return {@code true} if and only if a new thread-local variable has been created */ publicbooleansetIndexedVariable(int index, Object value){ Object[] lookup = indexedVariables; if (index < lookup.length) { Object oldValue = lookup[index]; lookup[index] = value; return oldValue == UNSET; } else { expandIndexedVariableTableAndSet(index, value); returntrue; } }
publicFastThreadLocal(){ index = InternalThreadLocalMap.nextVariableIndex(); }
/** * Returns the current value for the current thread */ @SuppressWarnings("unchecked") publicfinal V get(){ InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get(); Object v = threadLocalMap.indexedVariable(index); if (v != InternalThreadLocalMap.UNSET) { return (V) v; }
return initialize(threadLocalMap); }
private V initialize(InternalThreadLocalMap threadLocalMap){ V v = null; try { v = initialValue(); } catch (Exception e) { PlatformDependent.throwException(e); }