中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

ThreadLocal的基本定義是什么

發布時間:2021-12-17 14:30:06 來源:億速云 閱讀:145 作者:柒染 欄目:大數據

這期內容當中小編將會給大家帶來有關ThreadLocal的基本定義是什么,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

基本定義及解讀

官方釋義: http://docs.oracle.com/javase/8/docs/api/
This class provides thread-local variables. These variables differ from their normal counterparts in that each thread that accesses one (via its get or set method) has its own, independently initialized copy of the variable. ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (e.g., a user ID or Transaction ID).

  • 首先,每個線程都有變量的一個本地獨立副本,保證線程之間的數據不會互相影響

  • 可以通過重寫initialValue()方法實現ThreadLocal的默認初始值

    protected static final ThreadLocal<String> TL_EXAMPLE = 
                new ThreadLocal<String>() {  @Override
      protected String initialValue() {      return "default";
      }
    };
  • 為什么說明中建議定義為靜態static方法呢?不了解ThreadLocal原理的同學可能就糊涂了,既然是需要滿足多線程并發的,怎么會定義為一個靜態的類成員變量呢?
    只要大家看一下ThreadLocal的源碼就了解了,它有個靜態內部類叫ThreadLocalMap<ThreadLocal, Object>, 此Map在Thread類中被定義為了一個類成員變量,即每個Thread線程中都有一個獨立ThreadLocalMap副本,它的值只能被當前線程讀取和修改
    想像一下某個類中定義了多個ThreadLocal<?>變量,在當前線程中通過ThreadLocalMap.get(ThreadLocal)獲取到相應的變量副本。
    所以ThreadLocal變量本身不是副本,你可以把他當成一個代理,而ThreadLocalMap中存放了線程內的一個一個線程副本,ThreadLocal只是ThreadLocalMap內弱引用的Key(在ThreadLocal對象失效時可以及時的清理ThreadLocalMap)。
    這也回答了為什么ThreadLocal可以定義為static, 它只是Map中的Key而已,不同線程的Map副本獲取同一個Key的值完全不會沖突。

  類ThreadLocal:  
  public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);        if (e != null)            return (T)e.value;
    }    return setInitialValue();
  }  /**
  * ThreadLocalMap is a customized hash map suitable only for
  * maintaining thread local values. No operations are exported
  * outside of the ThreadLocal class. The class is package private to
  * allow declaration of fields in class Thread.  To help deal with
  * very large and long-lived usages, the hash table entries use
  * WeakReferences for keys. However, since reference queues are not
  * used, stale entries are guaranteed to be removed only when
  * the table starts running out of space.
  */
  static class ThreadLocalMap {...}

  類Thread:  /* ThreadLocal values pertaining to this thread. This map is maintained
   * by the ThreadLocal class. */
   ThreadLocal.ThreadLocalMap threadLocals = null;

Thread1 : 
       ThreadLocalMap1 : 
             <ThreadLocal1, String>
             <ThreadLocal2, Integer>Thread2 :
       ThreadLocalMap2 :             <ThreadLocal1, String>
             <ThreadLocal2, Integer>
  • 繼續延伸出一個問題: ThreadLocal類本身是線程安全的么?
    通過源碼看到不管是get,set還是createMap都沒有做任何的同步或者并發鎖。答案是安全的,因為實現都是基于當前線程的。

線程池與ThreadLocal變量的初始化

在線程池復用的情況下,若ThreaLocal數據沒有被清理掉,會被后面的請求復用然后拿到被你修改過的值!
之前在實現日志上下文LogContext的時候碰到了類似問題:

  1. 請求A進入Controller中, 開啟線程A,LogContext中記錄了大量的ThreadLocal中間變量值,在請求響應結束后,請求線程A回歸線程池;

  2. 請求B進入Controller中,復用線程A,LogContext會在之前變量值的基礎上繼續添加信息,這樣的日志信息成了疊加的了。

不管是基于自己實現的線程池,還是應用服務器(如Tomcat)的線程池,都需要小心這一點!
標準或者規范做法是在線程變量使用完畢之后,或者finally代碼塊中調用 threadLocalVariable.remove() 移除,以防被其他線程復用。

上述就是小編為大家分享的ThreadLocal的基本定義是什么了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

禹州市| 广水市| 平乐县| 富裕县| 木兰县| 永昌县| 承德县| 阜平县| 汉寿县| 乌什县| 绥芬河市| 铜川市| 杨浦区| 廉江市| 徐汇区| 栾川县| 略阳县| 英超| 南陵县| 南江县| 汾阳市| 公安县| 缙云县| 贵定县| 谷城县| 黄山市| 微博| 黄大仙区| 保亭| 光泽县| 郸城县| 卓资县| 盐亭县| 南靖县| 萨嘎县| 蓝山县| 吉木乃县| 郧西县| 石渠县| 长岭县| 柞水县|