Module  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必须被子类化,并且该方法被覆盖。 通常,将使用匿名内部类。

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

        public static <S> ThreadLocal<S> withInitial​(Supplier<? extends S> supplier)
        创建线程局部变量。 变量的初始值通过调用get上的Supplier方法来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