Threadlocal

ThreadLocal

说明:

JDK文档中这样解释ThreadLocal的:该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

所属包:
java.lang包下的类
案例:

在文档中JDK提供了Demo:

import java.util.concurrent.atomic.AtomicInteger;

public class UniqueThreadIdGenerator {
    private static final AtomicInteger uniqueId = new AtomicInteger(0);
    private static final ThreadLocal <Integer> uniqueNum = 
         new ThreadLocal<Integer>() {
             @Override protected Integer initialValue() {
                 return uniqueId.getAndIncrement();
        }
    };
 
    public static int getCurrentThreadId() {
        return uniqueId.get();
    }
}
多线程下的ThreadLocal

查看源码
  • set

      public void set(T value) {
          //获取当前线程
          Thread t = Thread.currentThread();
          //会调用下面的方法
          ThreadLocalMap map = getMap(t);
          if (map != null)
              map.set(this, value);
          else
              createMap(t, value);
      }
    
      ThreadLocalMap getMap(Thread t) {
          return t.threadLocals;
      }
      
      //ThreadLocalMap是什么呢?
      /**
        说明:他其实就是ThreadLocalMap中的一个静态内部类,里面定义了Entry保存数据。
      */
       static class Entry extends WeakReference<ThreadLocal<?>> {
              /** The value associated with this ThreadLocal. */
              Object value;
    
              Entry(ThreadLocal<?> k, Object v) {
                  super(k);
                  value = v;
              }
        }
    
  • get

        public T get() {
          Thread t = Thread.currentThread();
          ThreadLocalMap map = getMap(t);
          if (map != null) {
              ThreadLocalMap.Entry e = map.getEntry(this);
              if (e != null) {
                  @SuppressWarnings("unchecked")
                  T result = (T)e.value;
                  return result;
              }
          }
          return setInitialValue();
      }
      
      private T setInitialValue() {
          T value = initialValue();
          Thread t = Thread.currentThread();
          ThreadLocalMap map = getMap(t);
          if (map != null)
              map.set(this, value);
          else
              createMap(t, value);
          return value;
      }
    
  • remmove

       public void remove() {
           ThreadLocalMap m = getMap(Thread.currentThread());
           if (m != null)
               m.remove(this);
       }
    
注意事项:
  • 内存泄漏:
  • 说明:

1、Thread中有一个ThreadLocalMap,在set()或者get()的时候都会获取ThreadLocalMap。
2、ThreadLocalMap的key就是当前的ThreadLocal,值是我们自己设置的。
3、ThreadLocal是一个弱引用,当key被置为null时,会被垃圾回收,但是值得引用还在,所以每次操作完ThreadLocal之后,进行remove()。

posted @ 2020-12-26 22:21  蜗牛|ICU  阅读(25)  评论(0编辑  收藏  举报