对ThreadLocal的理解

1.我们先来聊聊ThreadLocal的里边自定义的 "hashCode "  (即: threadLocalHashCode ),他俩作用一样,所以第一次看源码,你就不要浪费时间在它身上,你就可以把它当做是  "hashCode "

    简单说明 threadLocalHashCode 生成原理: ThreadLocal 里边存在下边这三个东西

// 1.静态字段,为类所有,所有对象共享这个一个
private static AtomicInteger nextHashCode = new AtomicInteger();
//2.常量字段,每一个对象创建之初会被赋值
private final int threadLocalHashCode = nextHashCode();

 

//3.静态方法, 他的作用有两个: 第一个作用: 给常量字段 threadLocalHashCode 赋值; 第二个作用 :更新公共变量nextHashCode 的值;
private static int nextHashCode() {
    return nextHashCode.getAndAdd(HASH_INCREMENT);
}    

以上三个犬牙交错,导致最终的一个结果,如果你懒得分析,你就只需要明白一个结果就行了:那就是使用 ThreadLocal 这个类不仅可以创建对象,还可以创建多个对象,并且这每个对象都有一个常量字段 threadLocalHashCode,而且不同对象的常量字段threadLocalHashCode 的值还不一样;

       这个结果也可以简单理解为,每个 ThreadLocal 对象都有一个 threadLocalHashCode 并且他们的 threadLocalHashCode 值还不一样, 其实说到这里,你肯定觉得 ThreadLocal 的作者闲的蛋疼, 本来每个对象的 hashCode 都可以不一样,为啥非要搞个threadLocalHashCode ,这个你不要纠结,他本质上和 hashCode 在后边的使用上没有太大区别,只是ThreadLocal 的作者发现他的threadLocalHashCode 比 hashCode 用着更好(散列性好);

2.接下来我们聊聊 ThreadLocal 里边的内部类  ThreadLocalMap 是的,如果你愿意,你可以把它当成一个简单的 HashMap,但是要注意这TM是个内部类,这不是一个对象,换句话来说,这个 ThreadLocalMap  虽然在ThreadLocal 内部定义,但是并不是在ThreadLocal 对象中 保存这个集合对象, 这个集合对象在哪保存着呢? 是在线程里边,每个线程里边都有一个 ThreadLocalMap :

                             ThreadLocal.ThreadLocalMap threadLocals = null;

如果你觉得绕,那你可以简单理解: 就是 这个ThreadLocal 的作者,他觉得HashMap 不好用, 然后自己定义了一个ThreadLocalMap,但是此人又比较低调,所有没有把它放出来,而是把他放到了 ThreadLocal 类里边, 其实呢这个类放到哪儿都行;

3.最后要放大招了: 每个线程里边都有一个 threadLocals 这个是一个 ThreadLocal.ThreadLocalMap 类型的集合对象,这个集合对象当然是个双列集合,它的 key 就是 ThreadLocal对象, 他的值就是你用这个ThreadLocal放入的值; 不要慌,容我理一下:

其实我们为了理解清楚,可以假设下边一段代码:

public static void main(String[] args) {
    final  ThreadLocal<Object>   threadLocal_1 = new ThreadLocal<Object>(); //创建 一个ThreadLocal对象threadLocal_1 
    final ThreadLocal<Object> threadLocal_2 = new ThreadLocal<Object>();    //再创建一个ThreadLocal对象threadLocal_2 

    for (int i = 0; i <2 ; i++) {
        new Thread(new Runnable() {
            public void run() {
                //threadLocal_1 设置值,其实此时此刻是 threadLocal_1 给当前线程说,你过来,你不是持有一个集
                //合对象 threadLocals 吗? 我把自己作为 key, 通过set方法 给你一个值 value 和我对应,你保存一下;
                //那不就是相当于 每一个线程都 会拿threadLocal_1 作为key保存一个value
                // 一个 threadLocal_1对象,可以在每个线程的 threadLocals 集合中作为key 存储数据 value 
                // 也就是说每个线程的 threadLocals 集合中都有以 threadLocal_1 为key 的一条记录 (threadLocal_1 ,value)
                // 当然你不要误以为, ThreadLocal 和 线程是 一对多的关系 ,他们不是1对多的关系,
                // 因为同一个线程的 threadLocals 集合对象可以存储多个(key,value) 他们可以是这种情形
                // (threadLocal_1 ,value1), (threadLocal_2 ,value2), (threadLocal_3 ,value3)
                // 此时此刻不是一个线程 对应多个 ThreadLocal 对象吗? 所以他们最终是多对多的关系
                threadLocal_1.set(Thread.currentThread().getName()); 
                threadLocal_2.set(Thread.currentThread().getId());
                Object name = threadLocal_1.get();
                System.out.println(name);
                Object id = threadLocal_2.get();
                System.out.println(id);
            }
        }).start();
}

他的结果是:

Thread-0
Thread-1
12
13

我上边的代码注释已经说得很清楚了

ps: 附上一张图:看能不能帮助理解

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值