Netty原始碼分析第8章(高效能工具類FastThreadLocal和Recycler)---->第2節: FastThreadLocal的set方法
Netty原始碼分析第八章: 高效能工具類FastThreadLocal和Recycler
第二節: FastThreadLocal的set方法
上一小節我們學習了FastThreadLocal的建立和get方法的實現邏輯, 這一小節學習FastThreadLocal的set方法的實現邏輯
set方法, 其實就是修改執行緒共享物件, 作用域只是當前執行緒, 我們回顧根據上一小節demo中, 其中一個執行緒set物件的過程:
new Thread(new Runnable() {
@Override
public void run() {
Object obj = fastThreadLocalDemo.fastThreadLocalTest.get();
try {
for (int i=0;i<10;i++){
fastThreadLocalDemo.fastThreadLocalTest.set(new Object());
Thread.sleep(1000);
}
}catch (Exception e){
e.printStackTrace();
}
}
}).start();
我們跟到set方法中:
public final void set(V value) {
if (value != InternalThreadLocalMap.UNSET) {
set(InternalThreadLocalMap.get(), value);
} else {
remove();
}
}
這裡首先判斷我們當前設定的物件是不是UNSET, 因為這裡不是UNSET, 所以進到if塊中
if塊呼叫了過載的set方法, 引數仍然為InternalThreadLocalMap, 有關InternalThreadLocalMap的get操作, 上一小節已經進行過分析, 這裡不再贅述, 同時, 引數也傳入了set的value值
我們跟到過載的set方法中:
public final void set(InternalThreadLocalMap threadLocalMap, V value) {
if (value != InternalThreadLocalMap.UNSET) {
if (threadLocalMap.setIndexedVariable(index, value)) {
addToVariablesToRemove(threadLocalMap, this);
}
} else {
remove(threadLocalMap);
}
}
這裡我們重點關注 if (threadLocalMap.setIndexedVariable(index, value)) 這部分, 這裡通過threadLocalMap呼叫setIndexedVariable方法進行物件的設定, 傳入了當前FastThreadLocal的下標和value
我們跟到setIndexedVariable中:
public boolean setIndexedVariable(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);
return true;
}
}
這裡的邏輯其實和get非常型別, 都是直接通過索引操作的, 這裡根據索引值, 直接通過陣列下標的方式對元素進行設定, 熟悉上一小節內容的同學對此應該不會陌生
回到FastThreadLocal的Set方法中:
public final void set(V value) {
if (value != InternalThreadLocalMap.UNSET) {
set(InternalThreadLocalMap.get(), value);
} else {
remove();
}
}
剛才我們分析瞭如果修改的物件不是UNSET物件的操作, 如果修改的物件是UNSET物件, 則會呼叫remove方法
跟進remove方法:
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);
}
}
}
Object v = threadLocalMap.removeIndexedVariable(index) 這一步是根據索引index, 將值設定成UNSET
我們跟進removeIndexedVariable方法:
public Object removeIndexedVariable(int index) {
Object[] lookup = indexedVariables;
if (index < lookup.length) {
Object v = lookup[index];
lookup[index] = UNSET;
return v;
} else {
return UNSET;
}
}
這裡的邏輯也比較簡單, 根據index通過陣列下標的方式將元素設定成UNSET物件
回到remove方法中:
if (v != InternalThreadLocalMap.UNSET) 這裡判斷如果我們設定的值不是UNSET物件, 則會呼叫onRemoval方法
跟進onRemoval方法:
protected void onRemoval(@SuppressWarnings("UnusedParameters") V value) throws Exception { }
這裡是個空實現, 用於交給子類去完成
以上就是FastThreadLocal的set方法的實現