如何实现线程资源隔离的(实现原理)?
-
每个 Thread 对象都有一个 ThreadLocalMap 成员变量,这个Map使用一个Entry数组用来存储key,也就是hreadLocal对象本身,value为ThreadLocal#set方法中要设置的值,这个Entry继承了WeakReference弱引用
-
Thread的内部的ThreadLocalMap 有ThreadLocal来维护,每次获取和设置值时,ThreadLocalMap都会调用Thread.currentThread获取当前线程,然后从当前线程中获取ThreadLocalMap,最后从ThreadLocalMap 中获取或者设置值。所以,对于不同的线程,每次获取的值都是自己线程的ThreadLocalMap 中的值,形成了线程隔离
为什么key 的引用为弱引用?
-
如果主线程调用了线程a,线程a中第一次使用ThreadLocal对象的的set方法后,线程a内部的ThreadLocalMap中就多了个key,这个key就是ThreadLocal对象本身,这个时候到达ThreadLocal对象就有2个可达路径
-
一条为:从主线程-->线程a对象-->ThreadLocal对象
-
另外一条为:从线程a-->线程a的ThreadLocalMap对象-->ThreadLocalMap的key
-
-
如果key为强引用,那么当线程a不再使用ThreadLocal时,第一条的可达性路径就会断开,会被GC回收,是没有问题的;第二条路径是不会断开的而且key是强引用,所以这个键值对不会被GC回收,会造成内存泄露;
-
如果key为弱引用,那么第二条虽然不会断开,但是由于key是弱引用,所以会被GC回收,不会造成内存泄露
为什么value不设置为强引用?
如果value设置为弱引用,容易被GC回收掉,无法获取到value