ThreadLocal
概念
ThreadLocal:线程变量,是一个以ThreadLocal对象为键,任意对象为值的一个存储结构。
这个结构被附带在线程上,线程可以根据一个ThreadLocal
对象查询到绑定在这个线程的一个值
- Thread类中有一个成员变量属于
ThreadLocalMap
,他是一个map类,它的key是ThreadLocal的实例对象 - 当为
ThreadLocal
类型的变量执行set
操作时,首先获取当前线程的TheadLocalMap
变量,然后以ThreadLocal
类的对象为key,设定value
,get操作类似 ThreadLocal
变量的活动范围为某线程,是该线程独有的,这里是解决相同变量被多个线程访问的另一种思路,ThreadLocal.set()
到线程中的对象是该线程自己使用的对象,其他线程是无法访问的,线程终止后,该值作为垃圾被回收ThreadLocal
变量的工作原理是:每个线程独自拥有一个变量,对变量的操作是线程本地的操作
set/get注意点
每次
set/get
值,并不是直接使用线程id
作为TheadLocalMap
的key,而是使用ThreadLocal
作为key
- 如果直接使用线程id作为key,无法区分放入
ThreadLocalMap
的多个value - 使用
ThreadLocal
作为key,因为每一个ThreadLocal
对象都可以由ThreadLocalHashCode
属性唯一区分
那么如何保证ThreadLocalHashCode
唯一呢?
在ThreadLocal
类中,包含了一个static AtomicInteger nextHashCode
类变量和一个static final
修饰的常量(作为相邻两个nextHashCode
的差值)。因为nextHashCode
是类变量,所以每一次创建ThreadLocal
对象都可以保证nextHashCode
被更新到新的值,并且下一次调用ThreadLocal
类这个被更新的值仍然可用,同时使用的AtomicInteger
保证每次自增都是原子性的。
ThreadLocal和线程同步机制
他们都是为了解决多线程中相同变量的访问冲突问题
- 在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量,这时该变量是多个线程共享的,使用同步机制要求程序员分析什么时候对变量进行读写,较为麻烦
- 而
ThreadLocal
从另一个角度出发,它为每一个线程提供了一个独立的变量副本,从而隔离了多个线程对统一变量的访问冲突,因为每一个线程访问/操作的都是自己的本地变量,因此也没有必要对变量进行同步了,ThreadLocal
提供了线程安全的共享对象 - 总的来说,对于多线程资源共享问题,同步机制采取了时间换空间,而
ThreadLocal
采取了空间换时间,前者提供一份变量,让不同线程排队访问,后者为每一个线程提供一份变量,同时可以相互访问不受影响
ThreadLocalMap
ThreadLocalMap
作为hash表的一种实现方式,是通过开放寻址法来解决哈希冲突,与HashMap不同
开放寻址法
- 如果出现散列冲突,就重新探测一个空闲位置,将其插入,往散列表中插入数据时,如果某个数据经过散列函数散列之后,存储位置已经被占用,我们就从当前位置开始,以此往后寻找,看是否由空闲位置,直到找到为止
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!