成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

FastThreadLocal 是什么鬼?吊打 ThreadLocal 的存在?。?/h1>

開發(fā) 前端
ThreadLocal 大家都知道是線程本地變量,今天棧長再介紹一個神器:FastThreadLocal,從字面上看就是:Fast + ThreadLocal,一個快的 ThreadLocal?這到底是什么鬼呢?

 [[350411]]

ThreadLocal 大家都知道是線程本地變量,今天棧長再介紹一個神器:FastThreadLocal,從字面上看就是:Fast + ThreadLocal,一個快的 ThreadLocal?這到底是什么鬼呢?

一、FastThreadLocal 簡介

FastThreadLocal 并不是 JDK 自帶的,而是在 Netty 中造的一個輪子,Netty 為什么要重復造輪子呢?

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

  1. /** 
  2.  * A special variant of {@link ThreadLocal} that yields higher access performance when accessed from a 
  3.  * {@link FastThreadLocalThread}. 
  4.  * <p> 
  5.  * Internally, a {@link FastThreadLocal} uses a constant index in an array, instead of using hash code and hash table
  6.  * to look for a variable.  Although seemingly very subtle, it yields slight performance advantage over using a hash 
  7.  * tableand it is useful when accessed frequently. 
  8.  * </p><p> 
  9.  * To take advantage of this thread-local variable, your thread must be a {@link FastThreadLocalThread} or its subtype. 
  10.  * By defaultall threads created by {@link DefaultThreadFactory} are {@link FastThreadLocalThread} due to this reason. 
  11.  * </p><p> 
  12.  * Note that the fast path is only possible on threads that extend {@link FastThreadLocalThread}, because it requires 
  13.  * a special field to store the necessary state.  An access by any other kind of thread falls back to a regular 
  14.  * {@link ThreadLocal}. 
  15.  * </p> 
  16.  * 
  17.  * @param <V> the type of the thread-local variable 
  18.  * @see ThreadLocal 
  19.  */ 
  20. public class FastThreadLocal<V> { 
  21.  ... 

 

FastThreadLocal 是一個特殊的 ThreadLocal 變體,當從線程類 FastThreadLocalThread 中訪問 FastThreadLocalm時可以獲得更高的訪問性能。如果你還不知道什么是ThreadLocal,可以關(guān)注公眾號Java技術(shù)棧閱讀我之前分享的文章。

二、FastThreadLocal 為什么快?

在 FastThreadLocal 內(nèi)部,使用了索引常量代替了 Hash Code 和哈希表,源代碼如下:

  1. private final int index
  2.  
  3. public FastThreadLocal() { 
  4.     index = InternalThreadLocalMap.nextVariableIndex(); 
  1. public static int nextVariableIndex() { 
  2.     int index = nextIndex.getAndIncrement(); 
  3.     if (index < 0) { 
  4.         nextIndex.decrementAndGet(); 
  5.         throw new IllegalStateException("too many thread-local indexed variables"); 
  6.     } 
  7.     return index

FastThreadLocal 內(nèi)部維護了一個索引常量 index,該常量在每次創(chuàng)建 FastThreadLocal 中都會自動+1,從而保證了下標的不重復性。

這要做雖然會產(chǎn)生大量的 index,但避免了在 ThreadLocal 中計算索引下標位置以及處理 hash 沖突帶來的損耗,所以在操作數(shù)組時使用固定下標要比使用計算哈希下標有一定的性能優(yōu)勢,特別是在頻繁使用時會非常顯著,用空間換時間,這就是高性能 Netty 的巧妙之處。

要利用 FastThreadLocal 帶來的性能優(yōu)勢,就必須結(jié)合使用 FastThreadLocalThread 線程類或其子類,因為 FastThreadLocalThread 線程類會存儲必要的狀態(tài),如果使用了非 FastThreadLocalThread 線程類則會回到常規(guī) ThreadLocal。

Netty 提供了繼承類和實現(xiàn)接口的線程類:

  • FastThreadLocalRunnable
  • FastThreadLocalThread

 

Netty 也提供了 DefaultThreadFactory 工廠類,所有由 DefaultThreadFactory 工廠類創(chuàng)建的線程默認就是 FastThreadLocalThread 類型,來看下它的創(chuàng)建過程:

 

先創(chuàng)建 FastThreadLocalRunnable,再創(chuàng)建 FastThreadLocalThread,基友搭配,干活不累,一定要配合使用才“快”。

三、FastThreadLocal 實戰(zhàn)

要使用 FastThreadLocal 就需要導入 Netty 的依賴了:

  1. <dependency> 
  2.     <groupId>io.netty</groupId> 
  3.     <artifactId>netty-all</artifactId> 
  4.     <version>4.1.52.Final</version> 
  5. </dependency> 

寫一個測試小示例:

  1. import io.netty.util.concurrent.DefaultThreadFactory; 
  2. import io.netty.util.concurrent.FastThreadLocal; 
  3.  
  4. public class FastThreadLocalTest { 
  5.  
  6.     public static final int MAX = 100000; 
  7.  
  8.     public static void main(String[] args) { 
  9.         new Thread(() -> threadLocal()).start(); 
  10.         new Thread(() -> fastThreadLocal()).start(); 
  11.     } 
  12.  
  13.     private static void fastThreadLocal() { 
  14.         long start = System.currentTimeMillis(); 
  15.         DefaultThreadFactory defaultThreadFactory = new DefaultThreadFactory(FastThreadLocalTest.class); 
  16.  
  17.         FastThreadLocal<String>[] fastThreadLocal = new FastThreadLocal[MAX]; 
  18.  
  19.         for (int i = 0; i < MAX; i++) { 
  20.             fastThreadLocal[i] = new FastThreadLocal<>(); 
  21.         } 
  22.  
  23.         Thread thread = defaultThreadFactory.newThread(() -> { 
  24.             for (int i = 0; i < MAX; i++) { 
  25.                 fastThreadLocal[i].set("java: " + i); 
  26.             } 
  27.  
  28.             System.out.println("fastThreadLocal set: " + (System.currentTimeMillis() - start)); 
  29.  
  30.             for (int i = 0; i < MAX; i++) { 
  31.                 for (int j = 0; j < MAX; j++) { 
  32.                     fastThreadLocal[i].get(); 
  33.                 } 
  34.             } 
  35.         }); 
  36.         thread.start(); 
  37.         try { 
  38.             thread.join(); 
  39.         } catch (InterruptedException e) { 
  40.             e.printStackTrace(); 
  41.         } 
  42.  
  43.         System.out.println("fastThreadLocal total: " + (System.currentTimeMillis() - start)); 
  44.     } 
  45.  
  46.     private static void threadLocal() { 
  47.         long start = System.currentTimeMillis(); 
  48.         ThreadLocal<String>[] threadLocals = new ThreadLocal[MAX]; 
  49.  
  50.         for (int i = 0; i < MAX; i++) { 
  51.             threadLocals[i] = new ThreadLocal<>(); 
  52.         } 
  53.  
  54.         Thread thread = new Thread(() -> { 
  55.             for (int i = 0; i < MAX; i++) { 
  56.                 threadLocals[i].set("java: " + i); 
  57.             } 
  58.  
  59.             System.out.println("threadLocal set: " + (System.currentTimeMillis() - start)); 
  60.  
  61.             for (int i = 0; i < MAX; i++) { 
  62.                 for (int j = 0; j < MAX; j++) { 
  63.                     threadLocals[i].get(); 
  64.                 } 
  65.             } 
  66.         }); 
  67.         thread.start(); 
  68.         try { 
  69.             thread.join(); 
  70.         } catch (InterruptedException e) { 
  71.             e.printStackTrace(); 
  72.         } 
  73.  
  74.         System.out.println("threadLocal total: " + (System.currentTimeMillis() - start)); 
  75.     } 
  76.  

結(jié)果輸出:

 

可以看出,在大量讀寫面前,寫操作的效率差不多,但讀操作 FastThreadLocal 比 ThreadLocal 快的不是一個數(shù)量級,簡直是秒殺 ThreadLocal 的存在。

當我把 MAX 值調(diào)整到 1000 時,結(jié)果輸出:

 

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

上面的示例是單線程測試多個 *ThreadLocal,即數(shù)組形式,另外,我也測試了多線程單個 *ThreadLocal,這時候 FastThreadLocal 效率就明顯要落后于 ThreadLocal。。

最后需要說明的是,在使用完 FastThreadLocal 之后不用 remove 了,因為在 FastThreadLocalRunnable 中已經(jīng)加了移除邏輯,在線程運行完時會移除全部綁定在當前線程上的所有變量。

 

所以,使用 FastThreadLocal 導致內(nèi)存溢出的概率會不會要低于 ThreadLocal?

不一定,因為 FastThreadLocal 會產(chǎn)生大量的 index 常量,所謂的空間換時間,所以感覺 FastThreadLocal 內(nèi)存溢出的概率更大,但好在每次使用完都會自動 remove。

四、總結(jié)

Netty 中的 FastThreadLocal 在大量頻繁讀寫操作時效率要高于 ThreadLocal,但要注意結(jié)合 Netty 自帶的線程類使用,這可能就是 Netty 為什么高性能的奧妙之一吧!

如果沒有大量頻繁讀寫操作的場景,JDK 自帶的 ThreadLocal 足矣,并且性能還要優(yōu)于 FastThreadLocal。

本文轉(zhuǎn)載自微信公眾號「Java技術(shù)?!?,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Java技術(shù)棧公眾號。

 

責任編輯:武曉燕 來源: Java技術(shù)棧
相關(guān)推薦

2015-11-12 10:03:34

前端H5web

2021-11-10 12:13:02

HostonlyCookie瀏覽器

2017-04-03 15:35:13

知識體系架構(gòu)

2020-09-27 06:53:57

MavenCDNwrapper

2015-03-17 10:13:52

HTML5什么鬼

2021-07-06 10:17:07

Python LaunLinuxWindows

2019-10-30 10:13:15

區(qū)塊鏈技術(shù)支付寶

2021-09-13 15:17:52

FastThreadL源碼Java

2015-09-29 09:47:14

2022-01-12 12:35:36

Linuxworkqueue工作隊列

2021-10-11 08:58:34

Goroutine操作系統(tǒng)

2024-09-29 08:57:25

2019-01-07 12:40:19

2015-09-22 09:25:16

RTORPO災備技術(shù)

2022-09-07 08:41:57

SpringIstio分布式

2021-01-07 05:22:47

MySQL字段存儲

2015-07-16 10:49:31

虛擬化容器技術(shù)

2022-05-11 08:53:13

MySQL鎖機制

2019-01-17 14:35:01

2017-09-13 11:02:17

點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产精品三级 | 日韩欧美精品一区 | 亚洲va欧美va天堂v国产综合 | 国产高清在线 | 一区二区不卡高清 | 亚洲精品1区 | 久久网一区二区 | 国产精品成人久久久久a级 久久蜜桃av一区二区天堂 | 日韩在线精品视频 | 久久九 | 久久一区| 精品国产91亚洲一区二区三区www | 午夜ww| 日韩福利视频 | 国产99免费视频 | 毛片在线看片 | 欧美极品在线播放 | 亚洲视频第一页 | 久久久国产一区 | 二区欧美| 日韩在线观看中文字幕 | 99精品欧美一区二区蜜桃免费 | 欧美一区二区久久 | 亚洲欧美在线一区 | 成人二区 | 断背山在线观看 | 国产精品不卡 | 激情毛片 | 一区二区三区欧美大片 | 久久欧美高清二区三区 | 欧美午夜视频 | 亚洲九九 | 日本特黄a级高清免费大片 国产精品久久性 | 国产精品欧美日韩 | 成年视频在线观看福利资源 | 在线观看中文字幕 | 人碰人操 | 中文字幕成人av | 日本在线视 | 日韩三级电影一区二区 | 国产精品视频一二三区 |