[英]Java ThreadLocal static?
在 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 检索值可能无法获得“当前”线程设置的值。
我在这里想念什么?
根据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
我研究了java源代码,
java.lang.Thread Class
包含一个实例变量,如下所示。
ThreadLocal.ThreadLocalMap threadLocals = null;
因为threadLocals
变量是非静态的,所以应用程序中的每个线程(即Thread Class 的每个实例)都将拥有自己的 threadLocals 映射副本。
此映射的键是当前ThreadLocal 实例,值是您作为参数传递给 ThreadLocal.set() 的值。
当您尝试以ThreadLocal.get()
的形式获取值时,它会在内部从Current Thread的 ThreadLocalMap 中获取。
简单来说,您是从/向当前线程对象获取和设置值,而不是从/向您的ThreadLocal对象获取和设置值。
多个线程执行 B 的 someBMethod,最终会更新 SAME A 的静态 ThreadLocal 变量 myThreadLocal
是的,它们对同一个对象进行操作。 但是,重要的是要意识到ThreadLocal
的工作方式是每个线程都有自己的独立值。 因此,如果您有十个线程写入myThreadLocal
然后从myThreadLocal
读取,每个线程都会看到正确的(即它们自己的)值。
换句话说,哪个类或对象写入ThreadLocal
的实例并不重要。 重要的是在其上下文中执行操作的线程。
不,他们不会,这就是重点。 爪哇文档:
这些变量不同于它们的正常对应变量,因为每个访问一个(通过它的 get 或 set 方法)的线程都有它自己的、独立初始化的变量副本。 ThreadLocal 实例通常是希望将状态与线程相关联的类中的私有静态字段(例如,用户 ID 或事务 ID)。
多个线程执行 B 的 someBMethod,最终会更新 SAME A 的静态 ThreadLocal 变量 myThreadLocal
不,他们不会。 每个线程都有自己的 X 类型包含变量的实例。
从而达到了 ThreadLocal 变量的目的
不。
再看看Javadoc。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.