java.lang.Object
java.lang.ThreadLocal<T>
- 类型参数:
-
T
- 线程本地值的类型
- 直接已知子类:
-
InheritableThreadLocal
该类提供了线程本地变量。这些变量与其普通对应物不同,因为每个访问它们的线程(通过其
get
或set
方法)都有自己独立初始化的变量副本。ThreadLocal
实例通常是希望将状态与线程关联的类中的私有静态字段(例如用户ID或事务ID)。
例如,下面的类为每个线程生成本地唯一标识符。线程的ID在第一次调用ThreadId.get()
时被分配,并在后续调用中保持不变。
import java.util.concurrent.atomic.AtomicInteger; public class ThreadId { // 包含要分配的下一个线程ID的原子整数 private static final AtomicInteger nextId = new AtomicInteger(0); // 包含每个线程ID的线程本地变量 private static final ThreadLocal<Integer> threadId = new ThreadLocal<Integer>() { @Override protected Integer initialValue() { return nextId.getAndIncrement(); } }; // 返回当前线程的唯一ID,必要时进行分配 public static int get() { return threadId.get(); } }
每个线程只要线程存活且ThreadLocal
实例可访问,就会持有对其线程本地变量副本的隐式引用;线程消失后,其所有线程本地实例的副本都将被垃圾回收(除非存在对这些副本的其他引用)。
- 自 JDK 版本:
- 1.2
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionget()
返回当前线程的此线程本地变量副本中的值。protected T
返回此线程本地变量的当前线程的“初始值”。void
remove()
删除此线程本地变量的当前线程值。void
将此线程本地变量的当前线程副本设置为指定值。static <S> ThreadLocal
<S> withInitial
(Supplier<? extends S> supplier) 创建一个线程本地变量。
-
Constructor Details
-
ThreadLocal
public ThreadLocal()创建一个线程本地变量。- 参见:
-
-
Method Details
-
initialValue
返回此线程本地变量的当前线程的“初始值”。除非线程先前使用set(T)
方法调用了initialValue
方法,否则此方法将在线程首次使用get()
方法访问变量时被调用。通常,此方法每个线程最多调用一次,但在后续调用remove()
后跟get()
的情况下可能会再次调用。- 实现要求:
-
此实现简单地返回
null
;如果程序员希望线程本地变量具有除null
之外的初始值,则可以对ThreadLocal
进行子类化并覆盖此方法,或者可以使用方法withInitial(Supplier)
来构造ThreadLocal
。 - 返回:
- 此线程本地的初始值
- 参见:
-
withInitial
创建一个线程本地变量。变量的初始值由在Supplier
上调用get
方法确定。- 类型参数:
-
S
- 线程本地值的类型 - 参数:
-
supplier
- 用于确定初始值的供应商 - 返回:
- 新的线程本地变量
- 抛出:
-
NullPointerException
- 如果指定的供应商为null - 自 JDK 版本:
- 1.8
-
get
返回当前线程的此线程本地变量副本中的值。如果当前线程的变量没有值,则首先将其初始化为调用initialValue()
方法返回的值。- 返回:
- 此线程本地的当前线程值
-
set
将此线程本地变量的当前线程副本设置为指定值。大多数子类不需要覆盖此方法,仅依赖于initialValue()
方法来设置线程本地的值。- 参数:
-
value
- 要存储在此线程本地变量的当前线程副本中的值。
-
remove
public void remove()删除此线程本地变量的当前线程值。如果随后由当前线程读取此线程本地变量,则将通过调用其initialValue()
方法重新初始化其值,除非其值在此期间由当前线程设置。这可能导致当前线程中多次调用initialValue
方法。- 自 JDK 版本:
- 1.5
-