Java ThreadLocal静态?

时间:2013-04-27 07:51:02

标签: java multithreading java-ee 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();
    }
    ...
    }

Quesiton
现在假设这是一个web应用程序,并且线程按顺序执行:B.someBMethod,C.someCMethod。

执行B的someBMethod的多个线程将最终更新 SAME A的静态ThreadLocal变量myThreadLocal,从而击败了ThreadLocal变量的目的。 (根据文档推荐使用Static for Thread。)

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

我在这里缺少什么?

5 个答案:

答案 0 :(得分:51)

根据ThreadLocal

的定义
  

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

这意味着说2个帖子t1&amp; t2执行someBMethod()并最终设置x1&amp; x2X的实例)。现在当t1到来并执行someCMethod()时,它会获得x1(之前设置 本身)和t2得到x2

换句话说,拥有ThreadLocal的单个静态实例是安全的,因为在您调用set

时,内部会执行类似的操作
set(currentThread, value) //setting value against that particular thread

当你调用get

get(currentThread) //getting value for the thread

答案 1 :(得分:4)

我研究了java 源代码

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

    ThreadLocal.ThreadLocalMap threadLocals = null;

  2. 因为threadLocals变量非静态,应用程序中的每个线程(即 Thread Class的每个实例)都会拥有拥有它复制的threadLocals map。

      此地图的
    1. 当前 ThreadLocal实例,是您作为参数传递的值到ThreadLocal.set()。

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

      <的ThreadLocalMap中获取。 / LI>

      简单来说,你得到了&amp;从/向 ThreadLocal 对象设置值 线程对象,

答案 2 :(得分:3)

  

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

是的,它们在同一个对象上运行。但是,重要的是要认识到ThreadLocal的工作方式是每个线程都有自己独立的值。因此,如果您有十个帖子写入myThreadLocal然后从myThreadLocal读取,则每个帖子都会看到正确的(即他们自己的)值。

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

答案 3 :(得分:1)

  

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

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

  

从而超越了ThreadLocal变量的目的

没有

再看一下Javadoc。

答案 4 :(得分:1)

不,他们不会,这就是重点。 Javadoc :

  

这些变量与正常对应物的不同之处在于每个变量   访问一个(通过其get或set方法)的线程有自己的,   独立初始化变量的副本。 ThreadLocal实例   通常是希望关联的类中的私有静态字段   带有线程的状态(例如,用户ID或交易ID)。