Java ThreadLocal static?

在“线程本地”中设置值:

//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();
    }
    ...
    }

Quesiton
现在假设这是一个Web应用程序,线程执行:B.someBMethod,C.someCMethod,按此顺序排列。

执行 B 的 someBMethod 的多个线程最终将更新 SAME A 的静态 ThreadLocal 变量 myThreadLocal,从而击败 ThreadLocal 变量的用途。(根据文档,建议对 ThreadLocal 使用 static。

C的someCMethod,虽然从ThreadLocal检索值,但可能无法获得“当前”线程设置的值。

我在这里错过了什么?


答案 1

根据 ThreadLocal 类的定义

此类提供线程局部变量。这些变量与它们的正常对应变量的不同之处在于,访问一个变量的每个线程(通过其 get 或 set 方法)都有自己的、独立初始化的变量副本。ThreadLocal 实例通常是希望将状态与线程(例如,用户 ID 或事务 ID)相关联的类中的私有静态字段。

这意味着说2个线程和执行,它们最终分别设置和(的实例)。现在,当 come 和执行时,它会得到(这是之前自行设置的)并得到 .t1t2someBMethod()x1x2Xt1someCMethod()x1t2x2

换句话说,拥有 一个静态实例是安全的,因为在内部,当您调用时,它会执行类似操作。ThreadLocalset

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

当您调用 get 时

get(currentThread) //getting value for the thread

答案 2

我研究java源代码

  1. java.lang.Thread Class包含如下实例变量。

    ThreadLocal.ThreadLocalMap threadLocals = null;

因为变量是非静态的,所以应用程序中的每个线程(即 Thread 类的每个实例)都有自己的 threadLocals 映射副本threadLocals

  1. 此映射的关键当前 ThreadLocal 实例,value 是作为参数传递给 ThreadLocal.set() 的值。

  2. 当您尝试在内部获取值为 时,它将从当前线程的 ThreadLocalMap 中获取值。ThreadLocal.get()

简单来说,您正在从/到当前线程对象获取和设置值,而不是从/到您的 ThreadLocal 对象。