国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【源起Netty 外傳】FastThreadLocal怎么Fast?

gxyz / 411人閱讀

摘要:實現原理淺談幫助理解的示意圖中有一屬性,類型是的靜態內部類。剛剛說過,是一個中的靜態內部類,則是的內部節點。這個會在線程中,作為其屬性初始是一個數組的索引,達成與類似的效果。的方法被調用時,會根據記錄的槽位信息進行大掃除。

概述

FastThreadLocal的類名本身就充滿了對ThreadLocal的挑釁,“快男”FastThreadLocal是怎么快的?源碼中類注釋坦白如下:

/**
 * ...
 * Internally, a {@link FastThreadLocal} uses a constant index in an array, instead of using hash code and hash table,
 * to look for a variable.  Although seemingly very subtle, it yields slight performance advantage over using a hash
 * table, and it is useful when accessed frequently.
 * ...
 */

大概意思就是:用索引代替了ThreadLocal中的threadLocalHashCode,當請求頻繁時,這個小改動就會顯現其效果。
提到FastThreadLocal,就不得不提它的好基友FastThreadLocalThread,簡單來說,FastThreadLocal就是為FastThreadLocalThread量身打造的!

FastThreadLocalThread又是哪個單位的?且聽我慢慢道來……

FastThreadLocalThread

一般來說,Netty的client端,是這么創建的:

EventLoopGroup group = new NioEventLoopGroup();

沿著調用鏈,層層深入NioEventLoopGroup的構造函數,在MultithreadEventExecutorGroup構造塊,會看到這樣的邏輯:

if (executor == null) {
    executor = new ThreadPerTaskExecutor(newDefaultThreadFactory());
}

newDefaultThreadFactory()方法,功能如其名,創建了DefaultThreadFactory工廠:

protected ThreadFactory newDefaultThreadFactory() {
    return new DefaultThreadFactory(getClass());
}

DefaultThreadFactory工廠的產品,就是FastThreadLocalThread

ok,FastThreadLocalThread物種起源的事兒暫且放下,我們來簡單過一下原版ThreadLocal的工作機制。

ThreadLocal

ThreadLocal大家應該并不陌生,兩個最核心API

//賦值方法
public void set(T value);

//取值方法
public T get();

用以并發環境下,線程生命周期內的存取數據操作,隔離其它線程干擾。

實現原理淺談

幫助理解的示意圖:

Thread中有一屬性threadLocalsThreadLocal.ThreadLocalMap類型(ThreadLocalMap是ThreadLocal的靜態內部類)。ThreadLocal的set(T value)方法被調用時,會將參數value存放于當前線程的threadLocals中,想要獲取時,再從threadLocals中獲取。

剛剛說過,threadLocals是一個ThreadLocalMap(ThreadLocal中的靜態內部類),Entry則是ThreadLocalMap的內部節點。而ThreadLocalMap作為一個Map,人設是這樣的ThreadLocalMap>,T>,即key=ThreadLocalvalue=T

存入 set(T value)

public void set(T value) {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);    //根據當前線程獲取ThreadLocalMap
    if (map != null)
        map.set(this, value);    //map的key直接使用的當前ThreadLocal對象
    else
        createMap(t, value);
}  

線程向ThreadLocal存入時,第一次調用將在線程中分配一塊空間,初始大小為Entry[16]數組。然后,以作為key的ThreadLocal計算出hashCode,稍加計算得出Entry[16]數組的索引i。最后,為槽位Entry[i]賦值上value。

獲取 T get()

public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);    //找到與當前線程綁定的ThreadLocalMap
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;
            return result;
        }
    }
    return setInitialValue();
}

獲取時,先找到與當前線程綁定的ThreadLocalMap,然后你懂得……

聽上去一副滿滿的HashMap的套路,其實內在有很大差別,比如ThreadLocal的Entry實現了WeakReference弱引用)。

一個小問題

ThreadLocal為什么用Entry數組作為內置實現?而且初始就16位,還有擴容等實現。對某一線程而言,ThreadLocal不是只能存儲一個值嗎?這么想的話,用單個Object就能存儲了……

這個萬惡的問題,當時困擾了我很長時間,其實想通后很簡單:
Entry數組為了實現ThreadLocalMap,而ThreadLocalMap君的key是ThreadLocal,多個ThreadLocal都可以存儲在ThreadLocalMap中。沒錯,A線程只用一個ThreadLocal的話,確實用一個Object作為內置實現就搞定了,但是A線程使用多個ThreadLocal時,無法滿足!

FastThreadLocal

ThreadLocal就分析到這里,讓我們回歸FastThreadLocal。

結構及關鍵方法示意圖:

前文提到過,FastThreadLocal的關鍵是indexindex可以理解成一個FastThreadLocal對象的唯一ID。這個index會在FastThreadLocalThread線程中,作為其indexedVariables屬性(初始是一個Object[32]數組)的索引,達成與ThreadLocal類似的效果。

值得一提的是Object[] indexedVariables的第0位(Object[0]),用于存放未來會被釋放的數據,其實存儲的就是之前FastThreadLocal的set方法操作過的槽位信息。FastThreadLocal的remove方法被調用時,會根據記錄的槽位信息進行大掃除。

FastThreadLocal相關內容就聊到這里,更多細節請翻看源碼!

感謝

ThreadLocal源碼解讀

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68317.html

相關文章

  • 源起Netty 前傳】Linux網絡模型小記

    摘要:非阻塞模型這種也很好理解,由阻塞的死等系統響應進化成多次調用查看數據就緒狀態。復用模型,以及它的增強版就屬于該種模型。此時用戶進程阻塞在事件上,數據就緒系統予以通知。信號驅動模型應用進程建立信號處理程序時,是非阻塞的。 引言 之前的兩篇文章 FastThreadLocal怎么Fast?、ScheduledThreadPoolExecutor源碼解讀 搞的我心力交瘁,且讀源碼過程中深感功...

    Null 評論0 收藏0
  • 源起Netty 外傳】ServiceLoader詳解

    摘要:答曰摸索直譯為服務加載器,最終目的是獲取的實現類。代碼走起首先,要有一個接口形狀接口介紹然后,要有該接口的實現類。期具體實現依靠的內部類,感性趣的朋友可以自己看一下。總結重點在于可跨越包獲取,這一點筆者通過多模塊項目親測延時加載特性 前戲 netty源碼注釋有云: ... If a provider class has been installed in a jar file tha...

    MoAir 評論0 收藏0
  • 源起Netty 外傳】System.getPropert()詳解

    摘要:閱讀源碼時,發現很多,理所當然會想翻閱資料后,該技能,姿勢如下環境中的全部屬性全部屬性注意如果將本行代碼放在自定義屬性之后,會不會打出把自定義屬性也給獲取到可以結論會獲取目前環境中全部的屬性值,無論系統提供還是個人定義系統提供屬性代碼中定義 閱讀源碼時,發現很多System.getProperty(xxx),理所當然會想:whats fucking this? 翻閱資料后,Get該技能...

    lixiang 評論0 收藏0
  • 源起Netty 外傳】ScheduledThreadPoolExecutor源碼解讀

    引言 本文是源起netty專欄的第4篇文章,很明顯前3篇文章已經在偏離主題的道路上越來越遠。于是乎,我決定:繼續保持…… 使用 首先看看源碼類注釋中的示例(未改變官方示例邏輯,只是增加了print輸出和注釋) import java.time.LocalTime; import java.util.concurrent.Executors; import java.util.concurrent....

    funnyZhang 評論0 收藏0
  • 源起Netty 外傳】ScheduledThreadPoolExecutor源碼解讀

    引言 本文是源起netty專欄的第4篇文章,很明顯前3篇文章已經在偏離主題的道路上越來越遠。于是乎,我決定:繼續保持…… 使用 首先看看源碼類注釋中的示例(未改變官方示例邏輯,只是增加了print輸出和注釋) import java.time.LocalTime; import java.util.concurrent.Executors; import java.util.concurrent....

    Eastboat 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<