23

在 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 检索值可能无法获得“当前”线程设置的值。

我在这里想念什么?

4

5 回答 5

65

根据ThreadLocal类的定义

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

这意味着说 2 个线程t1&t2执行someBMethod(),它们最终分别设置x1& x2(Instances of X)。现在,当t1来执行someCMethod()它时,它会得到x1(之前由它自己设置)并得到.t2x2

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

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

当你调用 get

get(currentThread) //getting value for the thread
于 2013-04-27T07:55:39.073 回答
10

我研究了java源代码

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

    ThreadLocal.ThreadLocalMap threadLocals = null;

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

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

  2. 当您尝试在内部获取value asThreadLocal.get()时,它将从Current Thread的 ThreadLocalMap 中获取。

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

于 2016-09-01T21:56:20.857 回答
6

多个线程执行 B 的 someBMethod,最终会更新 SAME A 的静态 ThreadLocal 变量 myThreadLocal

是的,它们对同一个对象进行操作。然而,重要的是要认识到ThreadLocal工作方式是每个线程都有自己的、单独的值。因此,如果您有十个线程写入myThreadLocal然后从 读取myThreadLocal,每个线程都会看到正确的(即它们自己的)值。

换句话说,哪个类或对象写入ThreadLocal. 重要的是在其上下文中执行操作的线程。

于 2013-04-27T07:55:03.840 回答
1

多个线程执行 B 的 someBMethod,最终会更新 SAME A 的静态 ThreadLocal 变量 myThreadLocal

不,他们不会。每个线程都有自己的 X 类型包含变量的实例。

从而达到了 ThreadLocal 变量的目的

不。

再看看Javadoc。

于 2013-04-27T07:53:41.143 回答
1

不,他们不会,这就是重点。爪哇文档:

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

于 2013-04-27T07:53:56.983 回答