1. 程式人生 > >Netty原始碼分析第8章(高效能工具類FastThreadLocal和Recycler)---->第2節: FastThreadLocal的set方法

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方法的實現