模块  java.base
软件包  java.lang

Class ThreadLocal<T>

  • 已知直接子类:
    InheritableThreadLocal

    public class ThreadLocal<T>
    extends Object
    该类提供线程局部变量。 这些变量与它们的正常对应物的不同之处在于,访问其中的每个线程(通过其getset方法)具有其自己的,独立初始化的变量副本。 ThreadLocal实例通常是希望将状态与线程相关联的类中的私有静态字段(例如,用户ID或事务ID)。

    例如,下面的类生成每个线程本地的唯一标识符。 线程的id在第一次调用ThreadId.get()时分配,并在后续调用中保持不变。

      import java.util.concurrent.atomic.AtomicInteger;
    
     public class ThreadId {
         // Atomic integer containing the next thread ID to be assigned
         private static final AtomicInteger nextId = new AtomicInteger(0);
    
         // Thread local variable containing each thread's ID
         private static final ThreadLocal<Integer> threadId =
             new ThreadLocal<Integer>() {
                 @Override protected Integer initialValue() {
                     return nextId.getAndIncrement();
             }
         };
    
         // Returns the current thread's unique ID, assigning it if necessary
         public static int get() {
             return threadId.get();
         }
     } 

    只要线程处于活动状态且ThreadLocal实例可访问,每个线程都拥有对其线程局部变量副本的隐式引用; 在一个线程消失之后,它的所有线程局部实例副本都要进行垃圾收集(除非存在对这些副本的其他引用)。

    从以下版本开始:
    1.2
    • 方法详细信息

      • initialValue

        protected T initialValue()
        返回此线程局部变量的当前线程的“初始值”。 该方法将被调用的第一次一个线程访问与可变get()方法,除非线程先前调用的set(T)方法,在这种情况下initialValue方法将不被调用的线程。 通常,每个线程最多调用一次此方法,但如果后续调用remove()后跟get() ,则可以再次调用此方法。

        这个实现只返回null ; 如果程序员希望线程局部变量具有除null之外的初始值, ThreadLocal必须对ThreadLocal进行子类化,并且重写此方法。 通常,将使用匿名内部类。

        结果
        这个线程本地的初始值
      • withInitial

        public static <S> ThreadLocal<S> withInitial​(Supplier<? extends S> supplier)
        创建一个线程局部变量。 通过调用get上的Supplier方法确定变量的初始值。
        参数类型
        S - 线程本地值的类型
        参数
        supplier - 用于确定初始值的供应商
        结果
        一个新的线程局部变量
        异常
        NullPointerException - 如果指定的供应商为空
        从以下版本开始:
        1.8
      • get

        public T get()
        返回当前线程的此线程局部变量副本中的值。 如果变量没有当前线程的值,则首先将其初始化为调用initialValue()方法返回的值。
        结果
        当前线程的这个线程本地的值
      • set

        public void set​(T value)
        将此线程局部变量的当前线程副本设置为指定值。 大多数子类都不需要重写此方法,仅依靠initialValue()方法来设置线程局部的值。
        参数
        value - 要存储在此线程本地的当前线程副本中的值。
      • remove

        public void remove()
        删除此线程局部变量的当前线程值。 如果当前线程的此线程局部变量随后是read ,则其值将通过调用其initialValue()方法重新初始化,除非其当前线程在临时中的值为set 这可能导致在当前线程中多次调用initialValue方法。
        从以下版本开始:
        1.5