对Java Thread做的优化。
一 Demo
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class FastThreadLocalTest00 {
private final static FastThreadLocal<Long> v = new FastThreadLocal<Long>() { @Override protected Long initialValue() throws Exception { System.out.println("init"); return 0L; } };
public static void main(String[] args) throws InterruptedException { new FastThreadLocalThread(() -> { System.out.println("fast1 v1=" + v.get()); v.set(1L); System.out.println("fast1 v2=" + v.get()); v.remove(); System.out.println("fast1 v3=" + v.get()); }).start();
new FastThreadLocalThread(() -> { System.out.println("fast2 v1=" + v.get()); v.set(2L); System.out.println("fast2 v2=" + v.get()); v.remove(); System.out.println("fast2 v3=" + v.get()); }).start();
Thread.sleep(3_000); } }
|
二 FastThreadLocal
java1 2 3 4 5 6 7
|
private final int index;
public FastThreadLocal() { this.index = InternalThreadLocalMap.nextVariableIndex(); }
|
java1 2 3 4 5 6 7 8 9
| public static int nextVariableIndex() { int index = nextIndex.getAndIncrement(); if (index < 0) { nextIndex.decrementAndGet(); throw new IllegalStateException("too many thread-local indexed variables"); } return index; }
|
三 get方法
java1 2 3 4 5 6 7 8 9 10 11 12
| public final V get() { InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get(); Object v = threadLocalMap.indexedVariable(this.index); if (v != InternalThreadLocalMap.UNSET) { return (V) v; }
return initialize(threadLocalMap); }
|
1 InternalThreadLocalMap懒加载
java1 2 3 4 5 6 7 8
| public static InternalThreadLocalMap get() { Thread thread = Thread.currentThread(); if (thread instanceof FastThreadLocalThread) { return fastGet((FastThreadLocalThread) thread); } else { return slowGet(); } }
|
java1 2 3 4 5 6 7
| private static InternalThreadLocalMap fastGet(FastThreadLocalThread thread) { InternalThreadLocalMap threadLocalMap = thread.threadLocalMap(); if (threadLocalMap == null) { thread.setThreadLocalMap(threadLocalMap = new InternalThreadLocalMap()); } return threadLocalMap; }
|
java1 2 3
| private InternalThreadLocalMap() { this.indexedVariables = newIndexedVariableTable(); }
|
java1 2 3 4 5
| private static Object[] newIndexedVariableTable() { Object[] array = new Object[INDEXED_VARIABLE_TABLE_INITIAL_SIZE]; Arrays.fill(array, UNSET); return array; }
|
2 数组元素设值
java1 2
| Object v = threadLocalMap.indexedVariable(this.index);
|
java1 2 3 4 5
| public Object indexedVariable(int index) { Object[] lookup = indexedVariables; return index < lookup.length? lookup[index] : UNSET; }
|
3 首次get没值触发回调初始值
首次调用get没有数据的回调initialValue方法
java1 2 3 4 5 6 7 8 9 10 11 12
| private V initialize(InternalThreadLocalMap threadLocalMap) { V v = null; try { v = initialValue(); } catch (Exception e) { PlatformDependent.throwException(e); }
threadLocalMap.setIndexedVariable(index, v); addToVariablesToRemove(threadLocalMap, this); return v; }
|
四 set方法
java1 2 3 4 5 6 7 8 9 10
| public final void set(V value) { if (value != InternalThreadLocalMap.UNSET) { InternalThreadLocalMap threadLocalMap = InternalThreadLocalMap.get(); setKnownNotUnset(threadLocalMap, value); } else { remove(); } }
|
java1 2 3 4 5
| private void setKnownNotUnset(InternalThreadLocalMap threadLocalMap, V value) { if (threadLocalMap.setIndexedVariable(index, value)) { addToVariablesToRemove(threadLocalMap, this); } }
|
java1 2 3 4 5 6 7 8 9 10 11 12
| public boolean setIndexedVariable(int index, Object value) { Object[] lookup = this.indexedVariables; if (index < lookup.length) { Object oldValue = lookup[index]; lookup[index] = value; return oldValue == UNSET; } else { expandIndexedVariableTableAndSet(index, value); return true; } }
|
五 remove方法
java1 2 3
| public final void remove() { remove(InternalThreadLocalMap.getIfSet()); }
|
java1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public final void remove(InternalThreadLocalMap threadLocalMap) { if (threadLocalMap == null) { return; }
Object v = threadLocalMap.removeIndexedVariable(index); removeFromVariablesToRemove(threadLocalMap, this);
if (v != InternalThreadLocalMap.UNSET) { try { onRemoval((V) v); } catch (Exception e) { PlatformDependent.throwException(e); } } }
|