Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java线程本地静态?_Java_Multithreading_Jakarta Ee_Thread Local - Fatal编程技术网

Java线程本地静态?

Java线程本地静态?,java,multithreading,jakarta-ee,thread-local,Java,Multithreading,Jakarta 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 variab

在线程本地中设置值:

//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();
    }
    ...
    }
//类A保存静态ThreadLocal变量。
甲级{
public static ThreadLocal myThreadLocal=new ThreadLocal();
....
}
//类B方法在A的静态ThreadLocal变量中设置值
B类{
{
public void someBmethod(){
X=新的X();
A.myThreadLocal.set(x);
}
}
//类C检索线程局部变量中设置的值。
C类{
public void someCMethod(){
X=A.myThreadLocal.get();
}
...
}
问题
现在假设这是一个web应用程序,线程按顺序执行:B.someBMethod,C.someCMethod

执行B的someBMethod的多个线程最终将更新A的静态ThreadLocal变量myThreadLocal,从而超出ThreadLocal变量的用途。(根据文档,建议对ThreadLocal使用static。)

从ThreadLocal检索值时,C的someCMethod可能无法获取“当前”线程设置的值

我错过了什么

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

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

从而击败了ThreadLocal变量的真正目的

没有


再看看Javadoc。

不,他们不会,这就是重点

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

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

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

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

根据类的定义

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

也就是说,两个线程分别执行
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类
    包含一个实例变量,如下所示

    ThreadLocal.ThreadLocalMap threadLocals=null;

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

  • 此映射的键是,当前线程本地实例,值是作为参数传递给ThreadLocal.set()的值

  • 当您尝试
    ThreadLocal.get()
    的形式获取值时,在内部,它将从当前线程的ThreadLocalMap中获取


  • 简单地说,您正在从当前的线程对象获取和设置值,而不是从线程本地对象获取和设置值。

    在创建特定于线程的单例对象时,对此类的需求是至关重要的……Java文档非常不清楚,因此他提出了这个问题,因此,我在这里阅读问题和答案的原因是:d名称
    ThreadLocal
    回答了您的问题,更不用说Javadoc了。仅@NimChimpsky提供的摘录就足够了。