ThreadLocal 详解_扶朕去网吧的博客-CSDN博客
ThreadLocal可以简单看作一个map,每个线程保存一个map,这个map只能存储一组数据,key为线程id, value就是要存的值
一个ThreadLocal只能存储一个变量,如果要存多个就创建多个ThreadLocal对象
使用:
- ThreadLocal
threadLocal = new ThreadLocal<>(); - threadLocal.set("七淅在学Java");
- String i = threadLocal.get()
- // i = 七淅在学Java
对 ThreadLocal 的操作见第 3 点,可以看到 ThreadLocal 每次 set 方法都是对同个 key(因为是同个 ThreadLocal 对象,所以 key 肯定都是一样的)进行操作。
如此操作,看似对 ThreadLocal 的操作永远只会存 1 个值,那用长度为 1 的数组它不香吗?为什么还要用 16 长度呢?
好了,其实这里有个需要注意的地方,ThreadLocal 是可以存多个值的
那怎么存多个值呢?看如下代码:
- // 在主线程执行以下代码:
- ThreadLocal
threadLocal = new ThreadLocal<>(); - threadLocal.set("七淅在学Java");
- ThreadLocal
threadLocal2 = new ThreadLocal<>(); - threadLocal2.set("七淅在学Java2");
按代码执行后,看着是 new 了 2 个 ThreadLocal 对象,但实际上,数据的存储都是在同一个 ThreadLocal.ThreadLocalMap 上操作的。因此上述代码最终结果就是一个 ThreadLocalMap 存了 2 个不同 ThreadLocal 对象作为 key,对应 value 为 七淅在学Java、七淅在学Java2。
ThreadLocalMap是ThreadLocal的静态内部类。使用方式上:
1、两者都是Key和Value的形式,但是ThreadLocalMap的Key是指定的(ThreadLocal),HashMap的是任意值
2、都是使用了数组去存储数据
3、解决哈希冲突的算法不一样。HashMap使用的是链地址法。ThreadLocalMap使用的是开放寻址法。
ThreadLocal底层有一个默认容量为 16 的数组组成,k 是 ThreadLocal 对象的引用,v 是要放到 TheadLocal 的值。数组类似为 HashMap,对哈希冲突的处理不是用链表/红黑树处理,而是使用开放寻址法,即尝试顺序放到哈希冲突下标的下一个下标位置。该数组也可以进行扩容。
ThreadLocal是解决线程安全问题一个很好的思路,它通过为每个线程提供一个独立的变量副本解决了变量并发访问的冲突问题。在很多情况下,ThreadLocal比直接使用synchronized同步机制解决线程安全问题更简单,更方便,且结果程序拥有更高的并发性。
ThreadLocal可以用来解决多线程程序的并发问题,ThreadLocal并不是一个Thread,而是Thread的局部变量,当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“Local”所要表达的意思。