0%

threadlocal-faq

1. 用途

  1. 保存线程上下文, 可以再任意需要的地方获取
    如系统日志可以在任何地方获取到请求ID

  2. 线程安全的, 避免某些情况需要考虑线程安全必须同步带来的性能损失
    如 SimpleDateFormat 本身是线程不安全的, 如果要用这个类, 可以这样声明:

    1
    2
    3
    4
    5
    6
    7
    private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {

    @Override
    protected DateFormat initialValue() {
    return new SimpleDateFormat("yyyy-MM-dd")
    }
    }

2. 实现原理

ThreadLocal 将值维护在 ThreadLocalMap 中, 其中 key 为 ThreadLocal 对象.
每一个线程都有自己独立的 ThreadLocalMap; 在同一线程中, 多个 ThreadLocal 公用一个 ThreadLocalMap.

3. ThreadLocal 的回收机制

ThreadLocalMap 中的 Entry 是 WeakReference,
WeakReference 的特性是: 当系统进行垃圾回收时, 无论内存是否充足, 该对象仅仅被弱引用关联, 那么就会被回收.
这是为了防止 ThreadLocal 一致没有回收而导致的内存泄漏风险.

由于ThreadLocal 的回收机制, 通常 ThreadLocal 一般都声明成静态属性, 然后在请求处理完成之后, 主动 remove 掉.