1.ThreadLocal创建方式
ThreadLocal<String> threadlocal1= new ThreadLocal();
ThreadLocal<String> threadlocal2= new ThreadLocal();
ThreadLocal<String> threadlocal3= new ThreadLocal();
2.首先介绍一下,ThreadLocal的原理:
如下图所示,每一个线程都会有一个ThreadLocal.ThreadLocalMap 类型的变量threadlocals,每一个线程都有一个属于自己的ThreadLocalMap。
每创建一个Threadlocal对象,就相当于创建了一个Entry,这个Entry的key是ThreadLocal的弱引用,value是ThreadLocal的泛型值。
每一个线程在往ThreadLocal里设置值的时候,都是往自己的ThreadLocalMap中设置值,读也是以某个ThreadLocal作为引用,在自己的map里找对应的key,从而实现线程隔离的作用。
3.从JVM内存的层面说一说ThreadLocal
在JVM中,栈内存线程私有,存储了对象的引用,包括(当前线程、ThreadLocal线程)。堆内存线程共享,存储了对象的实例。
这里有几个问题
1.为什么会产生内存泄漏问题?
因为ThreadLocalMap中的每一个key都是ThreadLocal弱引用,当发生垃圾回收时,不管JVM的内存空间是否充足,都会回收该对象占用的内存。如果发生了垃圾回收,ThreadLocal被垃圾回收时,而ThreadLocalMap的生命周期和Thread一样,这就造成了内存泄漏的问题。解决方案是使用完ThreadLocal后,及时调用remove()方法释放内存空间。
2.为什么key要弱引用呢?
如果不弱引用,是强引用,当ThreadLocal释放掉内存后,ThreadLocal一直被key强引用着。这也会内存泄漏。