持续积累ThreadLocal技术【ThreadLocal原理 + ThreadLocal的坑 + ThreadLocal的最佳实践】

深入解析ThreadLocal:创建、API与内部存储结构详解

一、先从使用ThreadLocal开始

1、我看到的两种创建方式

1.1 ThreadLocal aThreadLocal = new ThreadLocal<>();

1.2 ThreadLocal aThreadLocal = ThreadLocal.withInitial(…)

1.3 为啥需要1.2提到的创建方式?直接new不就好了?

  • JDK源码中,就提到了ThreadLocal.withInitial(…):
    在这里插入图片描述

2、创建好了后,在使用aThreadLocal时,会涉及到3种重要的API

2.0 在理解3种API之前,又不得不了解下ThreadLocal内部的存储结构(不清楚存储结构,何谈对其的操作?)

2.0.1 3种API的概述
  • set方法:aThreadLocal.set(…)
  • get方法:aThreadLocal.get()
  • remove方法:aThreadLocal.remove()
2.0.2 ThreadLocal内部的存储结构
  • 图解:
    在这里插入图片描述

2.1 set方法:aThreadLocal.set(…)

2.1.1 JDK源码
public void set(T value) {
   
   
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    
  • 逻辑概述:一个线程Thread0去执行aThreadLocal.set(…)时,首先会取出自己的ThreadLocalMap,如果该map不存在,则创建并存储(ThreadLocal对象,value)。如果map存在,则直接存储(ThreadLocal对象,value)。
  • 对getMap(t)的解读见:“附录 1、ThreadLocal提供的set()、get()、remove()方法,都有一个getMap()方法。在这里补充说明下。”
2.1.1.1 重点关注:map.set(this, value); 实现原理
  • 方法签名:
private void set(ThreadLocal<?> key, Object value) {
   
   
	......
}

不贴完整源码了,毕竟在csdn上看源码并不是一个明智的决定~
对着IDEA上的源码,看本篇文章,才是不错的选择哟~

  • 思想:既然map(ThreadLocalMap)的存储结构是Entry[] table; 那显然要在table中找到一个位置table[i],将<key, value>放进去。
  • 如何查找呢?
    (1)简单的办法:遍历table。很显然JDK的设计者没有采用这种低效的方式。
    (2)哈希表的思路(学《数据结构与算法》的作用体现出来了!):对key求一个hash值,并将其转换为数组中的合法下标。
    实践:index = hash(key) % capacity (index = hash(key) & (capacity - 1) )更高效

6.1.2 哈希表简单实现 有必要学一学的~

如何查找?(哈希表的思路)
  • 回到set方法的源码:
Entry[] tab = table;
int len = tab.length;
int i = key.threadLocalHashCode & (len-1);

1)len是2的幂,len - 1表示成2进制,就是1…1,那么x & 1…1的范围一定是[0, 1…1],也就是数组下标的合法范围。
2)len不是2的幂,x & (len - 1)的范围也是[0, len - 1]。因为,len - 1表示为二进制,与它相与,最大情况下,便是1都没变成0,那么就是len - 1。因此,范围也是[0, len - 1]

  • 找到要放的位置了,但可能这个坑位已经被别人占了啊,这咋办?–> 遍历找下一个i。
for (Entry e = tab[i];
           e != null;
           e = tab[i = nextIndex(i, len)]) {
   
   
          ThreadLocal
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值