我理解的ThreadLocal

一、什么是ThreadLocal

  • java.lang包下的一个类;
  • 当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本;
public class PostContextUtils {
    /**
     * 确保线程安全
     */
    static ThreadLocal<PostServerContext> dataThreadLocal = new ThreadLocal<PostServerContext>();

     ...
}

ThreadLocal类的方法

  • public void set(T value); 设置当前线程的线程局部变量值
  • public T get(); 返回当前线程所对应的线程局部变量值
  • public void remove(); 删除前线程局部变量值,目的是为了减少内存的占用(TODO:线程池,线程并未真正被销毁,防止数据混淆)
  • protected Object initialValue(); 为了让子类覆盖而设计,缺省返回null值

二、实现原理

  • 在ThreadLocal类中有一个ThreadLocalMap,用于存储每一个线程的变量副本,key为当前线程对象,value为对应线程的变量副本。
  • 理解ThreadLocalMap类
public class ThreadLocal<T> {
    ...
    static class ThreadLocalMap {
        /**
         * The entries in this hash map extend WeakReference, using
         * its main ref field as the key (which is always a
         * ThreadLocal object).  Note that null keys (i.e. entry.get()
         * == null) mean that the key is no longer referenced, so the
         * entry can be expunged from table.  Such entries are referred to
         * as "stale entries" in the code that follows.
         */
        static class Entry extends WeakReference<ThreadLocal> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal k, Object v) {
                super(k);
                value = v;
            }
        }
    }
}
public class Thread implements Runnable {
    /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. 
     */
    ThreadLocal.ThreadLocalMap threadLocals = null;
}
ThreadLocalMap是ThreadLocal类的一个静态内部类,它实现了键值对的设置和获取;
每个线程中都有一个独立的ThreadLocalMap私有对象,它所存储的值,只能被当前线程读取和修改;
ThreadLocal类通过操作每一个线程特有的ThreadLocalMap对象,从而实现了变量访问在不同线程中的隔离;
  • ThreadLocalMap中的key是当前线程对象吗?
public class PostLogUtil {
    //用于保存一次请求的id,一次请求使用同一个id
    static ThreadLocal<Long> logInfoThreadLocal =new ThreadLocal<Long>();
    ...
}
public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value;
        }
        return setInitialValue();
}

三、拓展

  • 与同步机制比较

    同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。

  • 与私有变量比较

    避免参数传递,方便对象访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值