简体   繁体   English

Java ThreadLocal 是静态的吗?

[英]Java ThreadLocal static?

Setting a value in Thread Local:在 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 :问题
Now assuming this is a web-application, and threads execute: B.someBMethod, C.someCMethod in that order.现在假设这是一个 Web 应用程序,并且线程按顺序执行:B.someBMethod、C.someCMethod。

Multiple threads executing B's someBMethod, will end up updating the SAME A's static ThreadLocal variable myThreadLocal, thereby beating the very purpose of ThreadLocal variable.多个线程执行 B 的 someBMethod,最终会更新SAME A 的静态 ThreadLocal 变量 myThreadLocal,从而达到了 ThreadLocal 变量的目的。 (Using static for ThreadLocal is what is recommended as per documentation.) (根据文档,建议对 ThreadLocal 使用静态。)

The C's someCMethod, while retrieving value from ThreadLocal may not get the value set by the 'current' thread. C 的 someCMethod,虽然从 ThreadLocal 检索值可能无法获得“当前”线程设置的值。

What am i missing here?我在这里想念什么?

As per the definition of ThreadLocal class根据ThreadLocal类的定义

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.这些变量不同于它们的正常对应变量,因为每个访问一个(通过它的 get 或 set 方法)的线程都有它自己的、独立初始化的变量副本。 ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (eg, a user ID or Transaction ID). ThreadLocal 实例通常是希望将状态与线程相关联的类中的私有静态字段(例如,用户 ID 或事务 ID)。

That means say 2 threads t1 & t2 executes someBMethod() and they end up setting x1 & x2 (Instances of X ) respectively.这意味着说 2 个线程t1t2执行someBMethod()并且它们最终分别设置x1x2X的实例)。 Now when t1 comes and executes someCMethod() it gets x1 (which is set by itself earlier) and t2 gets x2 .现在,当t1来并执行someCMethod()时,它得到x1 (之前由它自己设置)并且t2得到x2

In other words, its safe to have a single static instance of ThreadLocal , because internally it does something like this when you invoke set换句话说,拥有ThreadLocal的单个静态实例是安全的,因为在内部调用set时它会执行类似的操作

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

and when you invoke get当你调用 get

get(currentThread) //getting value for the thread

I study the java source code ,我研究了java源代码

  1. java.lang.Thread Class contains a instance variable as below. java.lang.Thread Class包含一个实例变量,如下所示。

    ThreadLocal.ThreadLocalMap threadLocals = null;

Because threadLocals variable is non-static , Every thread in a application (ie, every instance of Thread Class ) will have it's own copy of threadLocals map.因为threadLocals变量是非静态的,所以应用程序中的每个线程(即Thread Class 的每个实例)都将拥有自己的 threadLocals 映射副本

  1. Key for this map is, current ThreadLocal instance, and value is the value which you pass as argument to ThreadLocal.set().此映射的当前ThreadLocal 实例,是您作为参数传递给 ThreadLocal.set() 的值。

  2. When you try to fetch value as ThreadLocal.get() , internally, it will fetch from the ThreadLocalMap of Current Thread .当您尝试以ThreadLocal.get()的形式获取值时,它会在内部从Current Thread的 ThreadLocalMap 中获取。

In simple terms , you are getting & setting values from/to your current Thread Object, not from/to your ThreadLocal object.简单来说,您是从/向当前线程对象获取和设置值,而不是从/向您的ThreadLocal对象获取和设置值。

Multiple threads executing B's someBMethod, will end up updating the SAME A's static ThreadLocal variable myThreadLocal多个线程执行 B 的 someBMethod,最终会更新 SAME A 的静态 ThreadLocal 变量 myThreadLocal

Yes, they operate on the same object.是的,它们对同一个对象进行操作。 However, it is important to realize that the way ThreadLocal works is that each thread has its own, separate value.但是,重要的是要意识到ThreadLocal的工作方式是每个线程都有自己的独立值。 Thus if you have ten threads writing to myThreadLocal and then reading from myThreadLocal , each will see the correct (ie their own) value.因此,如果您有十个线程写入myThreadLocal然后从myThreadLocal读取,每个线程都会看到正确的(即它们自己的)值。

To put it another way, it does not matter which class or object writes to an instance of ThreadLocal .换句话说,哪个类或对象写入ThreadLocal的实例并不重要。 What matters is the thread in whose context the operation is performed.重要的是在其上下文中执行操作的线程

No they won't, thats the point.不,他们不会,这就是重点。 Javadoc : 爪哇文档:

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.这些变量不同于它们的正常对应变量,因为每个访问一个(通过它的 get 或 set 方法)的线程都有它自己的、独立初始化的变量副本。 ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (eg, a user ID or Transaction ID). ThreadLocal 实例通常是希望将状态与线程相关联的类中的私有静态字段(例如,用户 ID 或事务 ID)。

Multiple threads executing B's someBMethod, will end up updating the SAME A's static ThreadLocal variable myThreadLocal多个线程执行 B 的 someBMethod,最终会更新 SAME A 的静态 ThreadLocal 变量 myThreadLocal

No they won't.不,他们不会。 Every thread has its own instance of the contained variable of type X.每个线程都有自己的 X 类型包含变量的实例。

thereby beating the very purpose of ThreadLocal variable从而达到了 ThreadLocal 变量的目的

No.不。

Have another look at the Javadoc.再看看Javadoc。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM