FastThreadLocal 為什麼快

2021-10-10 06:01:10 字數 2958 閱讀 9524

threadlocal 大家都知道是執行緒本地變數,今天棧長再介紹乙個神器:fastthreadlocal,從字面上看就是:fast + threadlocal,乙個快的 threadlocal?這到底是什麼鬼呢?

一、fastthreadlocal 簡介

fastthreadlocal 並不是 jdk 自帶的,而是在 netty 中造的乙個輪子,netty 為什麼要重複造輪子呢?

來看下它原始碼中的注釋定義:

二、fastthreadlocal 為什麼快?

在 fastthreadlocal 內部,使用了索引常量代替了 hash code 和雜湊表,源**如下:

private final int index;

public fastthreadlocal()

public static int nextvariableindex()

return index;

}fastthreadlocal 內部維護了乙個索引常量 index,該常量在每次建立 fastthreadlocal 中都會自動+1,從而保證了下標的不重複性。

這要做雖然會產生大量的 index,但避免了在 threadlocal 中計算索引下標位置以及處理 hash 衝突帶來的損耗,所以在運算元組時使用固定下標要比使用計算雜湊下標有一定的效能優勢,特別是在頻繁使用時會非常顯著,用空間換時間,這就是高效能 netty 的巧妙之處。如果你不知道netty怎麼使用,可以去看一下詳細操作。

要利用 fastthreadlocal 帶來的效能優勢,就必須結合使用 fastthreadlocalthread 執行緒類或其子類,因為 fastthreadlocalthread 執行緒類會儲存必要的狀態,如果使用了非 fastthreadlocalthread 執行緒類則會回到常規 threadlocal。

netty 提供了繼承類和實現介面的執行緒類:

fastthreadlocalrunnable

fastthreadlocalthread

netty 也提供了 defaultthreadfactory 工廠類,所有由 defaultthreadfactory 工廠類建立的執行緒預設就是 fastthreadlocalthread 型別,來看下它的建立過程:

先建立 fastthreadlocalrunnable,再建立 fastthreadlocalthread,**搭配,幹活不累,一定要配合使用才「快」。

三、fastthreadlocal 實戰

要使用 fastthreadlocal 就需要匯入 netty 的依賴了:

io.netty netty-all 4.1.52.final 寫乙個測試小示例:

import io.netty.util.concurrent.defaultthreadfactory;

import io.netty.util.concurrent.fastthreadlocal;

public class fastthreadlocaltest

private static void fastthreadlocal()

thread thread = defaultthreadfactory.newthread(() ->

system.out.println("fastthreadlocal set: " + (system.currenttimemillis() - start));

for (int i = 0; i < max; i++)

}});

thread.start();

try catch (interruptedexception e)

system.out.println("fastthreadlocal total: " + (system.currenttimemillis() - start));

}private static void threadlocal()

thread thread = new thread(() ->

system.out.println("threadlocal set: " + (system.currenttimemillis() - start));

for (int i = 0; i < max; i++)

}});

thread.start();

try catch (interruptedexception e)

system.out.println("threadlocal total: " + (system.currenttimemillis() - start));

}}結果輸出:

可以看出,在大量讀寫面前,寫操作的效率差不多,但讀操作 fastthreadlocal 比 threadlocal 快的不是乙個數量級,簡直是秒殺 threadlocal 的存在。

當我把 max 值調整到 1000 時,結果輸出:

讀寫操作不多時,threadlocal 明顯更勝一籌!

上面的示例是單執行緒測試多個 *threadlocal,即陣列形式,另外,我也測試了多執行緒單個 *threadlocal,這時候 fastthreadlocal 效率就明顯要落後於 threadlocal。。

所以,使用 fastthreadlocal 導致記憶體溢位的概率會不會要低於 threadlocal?

不一定,因為 fastthreadlocal 會產生大量的 index 常量,所謂的空間換時間,所以感覺 fastthreadlocal 記憶體溢位的概率更大,但好在每次使用完都會自動 remove。

四、總結

netty 中的 fastthreadlocal 在大量頻繁讀寫操作時效率要高於 threadlocal,但要注意結合 netty 自帶的執行緒類使用,這可能就是 netty 為什麼高效能的奧妙之一吧!

如果沒有大量頻繁讀寫操作的場景,jdk 自帶的 threadlocal 足矣,並且效能還要優於 fastthreadlocal。

為什麼為什麼為什麼為什麼為什麼你要做一名程式設計師?

from 本文是從 why why why why why are you a developer?這篇文章翻譯而來。做乙個程式設計師很忙,你需要去寫 去建立meme,去進行測試,以及隨時關注最新最熱的gem 開源軟體技術。最近,我一直在想讓自己的節奏慢下來,去做一些心裡一直想做但沒有去做的事,去思...

03 為什麼封裝,為什麼有this?

為什麼封裝?嬰兒太多了,所以我們會考慮將每個出生的嬰兒的 文件 我們都會放於乙個盒子裡 這樣方便以後我們查詢他的身份證資訊。於是在這個盒子上,我們打了乙個孔,叫set 方法,如果是身份證,我們就取名 setcode 方法,這樣就將乙個人的身份證資訊建立 set了。但放進去後,我們有時候還需要檢驗這個...

為什麼無法訪問mysql mysql為什麼無法訪問

mysql無法訪問有兩種情況 乙個是mysql沒有分配許可權,使用grant語句分配訪問許可權即可格式 grant 許可權 on 資料庫名.表名 使用者 登入主機 identified by 使用者密碼 grant select,update,insert,delete on to zhxia id...