簡體   English   中英

Java ThreadLocal 是靜態的嗎?

[英]Java ThreadLocal static?

在 Thread Local 中設置一個值:

//Class A holds the static ThreadLocal variable.

    Class A{

    public static ThreadLocal<X> myThreadLocal = new ThreadLocal<X>();             
    ....
    }


//A Class B method sets value in A's static ThreadLocal variable 
    class B{
    {
         public void someBmethod(){
             X x = new X();
             A.myThreadLocal.set(x);
         }
    }


//Class C retrieves the value set in A's Thread Local variable.

    Class C {

    public void someCMethod(){
         X x = A.myThreadLocal.get();
    }
    ...
    }

問題
現在假設這是一個 Web 應用程序,並且線程按順序執行:B.someBMethod、C.someCMethod。

多個線程執行 B 的 someBMethod,最終會更新SAME A 的靜態 ThreadLocal 變量 myThreadLocal,從而達到了 ThreadLocal 變量的目的。 (根據文檔,建議對 ThreadLocal 使用靜態。)

C 的 someCMethod,雖然從 ThreadLocal 檢索值可能無法獲得“當前”線程設置的值。

我在這里想念什么?

根據ThreadLocal類的定義

此類提供線程局部變量。 這些變量不同於它們的正常對應變量,因為每個訪問一個(通過它的 get 或 set 方法)的線程都有它自己的、獨立初始化的變量副本。 ThreadLocal 實例通常是希望將狀態與線程相關聯的類中的私有靜態字段(例如,用戶 ID 或事務 ID)。

這意味着說 2 個線程t1t2執行someBMethod()並且它們最終分別設置x1x2X的實例)。 現在,當t1來並執行someCMethod()時,它得到x1 (之前由它自己設置)並且t2得到x2

換句話說,擁有ThreadLocal的單個靜態實例是安全的,因為在內部調用set時它會執行類似的操作

set(currentThread, value) //setting value against that particular thread

當你調用 get

get(currentThread) //getting value for the thread

我研究了java源代碼

  1. java.lang.Thread Class包含一個實例變量,如下所示。

    ThreadLocal.ThreadLocalMap threadLocals = null;

因為threadLocals變量是非靜態的,所以應用程序中的每個線程(即Thread Class 的每個實例)都將擁有自己的 threadLocals 映射副本

  1. 此映射的當前ThreadLocal 實例,是您作為參數傳遞給 ThreadLocal.set() 的值。

  2. 當您嘗試以ThreadLocal.get()的形式獲取值時,它會在內部從Current Thread的 ThreadLocalMap 中獲取。

簡單來說,您是從/向當前線程對象獲取和設置值,而不是從/向您的ThreadLocal對象獲取和設置值。

多個線程執行 B 的 someBMethod,最終會更新 SAME A 的靜態 ThreadLocal 變量 myThreadLocal

是的,它們對同一個對象進行操作。 但是,重要的是要意識到ThreadLocal的工作方式是每個線程都有自己的獨立值。 因此,如果您有十個線程寫入myThreadLocal然后從myThreadLocal讀取,每個線程都會看到正確的(即它們自己的)值。

換句話說,哪個類或對象寫入ThreadLocal的實例並不重要。 重要的是在其上下文中執行操作的線程

不,他們不會,這就是重點。 爪哇文檔:

這些變量不同於它們的正常對應變量,因為每個訪問一個(通過它的 get 或 set 方法)的線程都有它自己的、獨立初始化的變量副本。 ThreadLocal 實例通常是希望將狀態與線程相關聯的類中的私有靜態字段(例如,用戶 ID 或事務 ID)。

多個線程執行 B 的 someBMethod,最終會更新 SAME A 的靜態 ThreadLocal 變量 myThreadLocal

不,他們不會。 每個線程都有自己的 X 類型包含變量的實例。

從而達到了 ThreadLocal 變量的目的

不。

再看看Javadoc。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM