【菠萝】ThreadLocal解析

153 阅读2分钟

总结什么是ThreadLocal

ThreadLoacl是用于线程隔离的一个类。

使用场景

如果需要每个线程都拥有一份属于自己的变量副本,互相之间相互不影响,可以用ThreadLocal实现,天然是线程安全的。

image.png

image.png

image.png

原理

ThreadLocal内部维护的是一个ThreadLocalMap,TreadLocalMap的数据结构是数组+entry, 其中key存储的是当前的线程ThreadLocal,value就是实际的值。

内存泄漏

使用ThreadLocal要注意内存泄漏问题,因为ThreadLocalMap中的key,是弱引用,而value是强引用。所谓弱引用就是说,当发生垃圾回收的时候,key是会被回收的,这样的话,key就会变成null值 ,而value是强引用,不会被回收,所以如果多个线程,循环利用的过程中,就会出现内存泄漏的问题

内存泄漏的解决办法

解决办法很简单,在get完threadLocal中的数据以后,使用他的Remove方法,即可

ThreadLocalMap解决hash冲突的办法

由于ThreadLoaclMap并不是真正意义上的HashMap,没有通过维护一个链表来解决hash冲突,所以对于ThreadLoaclMap来说,他是通过线性探测法来解决冲突问题,也就是说,如果当前数组中的位置已经有其他entry,那么就会简单的把新的entry放到后面的位置中。

父子通信问题

如果对于一个主线程中的ThreadLoacl,其下的多个子线程期望获取到主线程中ThreadLocal中的数据,可以通过InheritableThreadLocal这个类来实现。

image.png

可以看到用普通的ThreadLocal子线程获取不到主线程的数据。

image.png

更改了实现类以后,可以正常获取到主线程的数据,实现父子通信