Java 对ThreadLocal感到困惑

Java 对ThreadLocal感到困惑,java,thread-local,Java,Thread Local,我今天早上才知道ThreadLocal。我读到它应该是最终的和静态的,比如: private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static final ThreadLocal ThreadLocal=new ThreadLocal(); (会话是休眠会话) 我的困惑是:因为它是静态的,所以JVM中的任何线程都可以使用它。然而,它将保存

我今天早上才知道ThreadLocal。我读到它应该是最终的和静态的,比如:

private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static final ThreadLocal ThreadLocal=new ThreadLocal();
(会话是休眠会话)


我的困惑是:因为它是静态的,所以JVM中的任何线程都可以使用它。然而,它将保存访问它的每个线程的本地信息?我正试着把我的头绕在这件事上,所以如果这件事不清楚,我道歉。应用程序中的每个线程都可以访问同一个ThreadLocal对象,但ThreadLocal对象将存储每个线程的本地对象?

对于特定问题,您始终可以访问ThreadLocal的同一个实例,但此实例为调用该方法的每个线程返回不同的值

这就是重点:很容易找到对象,但每个线程都有自己的特定值。例如,您可以确保您的特定值不会被两个不同的线程访问


您可以(从概念上)将其视为一种
HashMap
,它总是以
Thread.currentThread()
作为键进行访问。

是的,实例将是相同的,但在设置和检索时,代码会附加您使用
Thread.currentThread()
设置的值,因此,当使用方法
set
get
访问时,值集就可以在当前线程中访问

这真的很容易理解

假设每个
线程
都有一个映射,该映射将一个值关联到
线程本地
实例。每次对
ThreadLocal
执行get或set时,
ThreadLocal
的实现都会获取与当前
线程相关联的映射(
Thread.currentThread()
),并在该映射中使用自身作为键执行
get
set

示例:

ThreadLocal tl = new ThreadLocal();
tl.set(new Object()); // in this moment the implementation will do something similar to Thread.getCurrentThread().threadLocals.put(tl, [object you gave]) 

Object obj = t1.get(); // in this moment the implementation will do something similar to Thread.getCurrentThread().threadLocals.get(tl)

有趣的是,
ThreadLocal
是分层的,这意味着如果您为父线程定义了一个值,那么可以从子线程访问它。

因为特定于线程的值不是存储在
ThreadLocal
对象中,而是存储在's
ThreadLocalMap
中。
ThreadLocal
对象仅作为这些映射中的键


有关详细信息,请阅读
ThreadLocal
和子类的JavaDoc,或者,如果您对实现感兴趣,请阅读最近的每一个JDKs src.zip中提供的源代码。

注意在共享环境中部署的web应用程序中使用它。线程本地将在所有上下文中泄漏,取消部署后,线程本地中的引用将不会被垃圾收集。每次请求后都需要手动删除数据。这似乎是矛盾的
ThreadLocal
在每个线程中都应该是唯一的,但是静态对象在每个线程之间共享。我正要问同样的问题。你说想象在
ThreadLocal
中有一个地图。我明白这个概念。线程id是键,唯一实例是值。因此,整个
ThreadLocal
对象是静态的,每个线程持有一个值。它实际上是用内部映射实现的吗?我只是查看了源代码。它有一个内部映射。