Java ThreadLocal静态?
在线程本地中设置值:
//Class A holds the static ThreadLocal variable. Class A{ public static ThreadLocal myThreadLocal = new ThreadLocal(); .... } //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个线程t1
和t2
执行someBMethod()
,它们最终分别设置x1
和x2
( X
实例)。 现在,当t1
到来并执行someCMethod()
它得到x1
(它自己先前设置 ), t2
得到x2
。
换句话说,拥有ThreadLocal
的单个静态实例是安全的,因为在调用set
时,它在内部执行类似这样的操作
set(currentThread, value) //setting value against that particular thread
当你调用get
get(currentThread) //getting value for the thread
执行B的someBMethod的多个线程将最终更新SAME A的静态ThreadLocal变量myThreadLocal
是的,它们在同一个对象上运行。 但是,重要的是要认识到ThreadLocal
工作方式是每个线程都有自己独立的值。 因此,如果您有十个线程写入myThreadLocal
然后从myThreadLocal
读取,则每个线程都会看到正确的(即它们自己的)值。
换句话说,哪个类或对象写入ThreadLocal
的实例并不重要。 重要的是在其上下文中执行操作的线程 。
我研究了java 源代码 ,
-
java.lang.Thread Class
包含一个实例变量,如下所示。ThreadLocal.ThreadLocalMap threadLocals = null;
因为threadLocals
变量是非静态的 ,所以应用程序中的每个线程(即Thread类的每个实例 )都将拥有它自己的threadLocals map 副本 。
-
此映射的键是, 当前 ThreadLocal实例, value是您作为参数传递给ThreadLocal.set()的值。
-
当您尝试在内部获取值为
ThreadLocal.get()
时,它将从当前线程的ThreadLocalMap中获取。
简单来说 ,您将从/向当前线程对象获取值, 而不是从/向ThreadLocal对象设置值。
执行B的someBMethod的多个线程将最终更新SAME A的静态ThreadLocal变量myThreadLocal
不,他们不会。 每个线程都有自己的包含X类型变量的实例。
从而击败了ThreadLocal变量的目的
没有。
再看一下Javadoc。
不,他们不会,这就是重点。 Javadoc:
这些变量与它们的正常对应物的不同之处在于,访问一个变量的每个线程(通过其get或set方法)都有自己独立初始化的变量副本。 ThreadLocal实例通常是希望将状态与线程相关联的类中的私有静态字段(例如,用户ID或事务ID)。