ThreadLocal、ThreadLocalMap弱引用key

来源:互联网 发布:hadoop与java 编辑:程序博客网 时间:2024/06/05 10:53

ThreadLocal

ThreadLocal类为每一个线程都维护了自己独有的变量拷贝。每个线程都拥有了自己独立的一个变量,竞争条件被彻底消除了,那就没有任何必要对这些线程进行同步,它们也能最大限度的由CPU调度,并发执行。并且由于每个线程在访问该变量时,读取和修改的,都是自己独有的那一份变量拷贝,变量被彻底封闭在每个访问的线程中,并发错误出现的可能也完全消除了。对比前一种方案,这是一种以空间来换取线程安全性的策略。

JDK1.6的源码里是通过ThreadLocalMap实现的

JDK1.7中已经没有了ThreadLocalMap,具体实现有空翻下源码


ThreadLocalMap的弱引用会使其数据在GC时被回收掉吗

ThreadLocal源码中有个静态的内部类ThreadLocalMap,里面有个Entry类

        static class Entry extends WeakReference<ThreadLocal> {            /** The value associated with this ThreadLocal. */            Object value;            Entry(ThreadLocal k, Object v) {                super(k);                value = v;            }        }
其中key是弱引用的



    每个thread中都存在一个map, map的类型是ThreadLocal.ThreadLocalMap. Map中的key为一个threadlocal实例. 这个Map的确使用了弱引用,不过弱引用只是针对key. 每个key都弱引用指向threadlocal. 像上面code中的例子,当把threadlocal实例tl置为null以后,没有任何强引用指向threadlocal实例,所以 threadlocal将会被gc回收. 但是,我们的value却不能回收,因为存在一条从current thread连接过来的强引用. 只有当前thread结束以后,current thread就不会存在栈中,强引用断开,Current Thread, Map, value将全部被GC回收.

从中可以看出,弱引用只存在于key上,所以key会被回收. 而value还存在着强引用.只有thead退出以后,value的强引用链条才会断掉

需要注意的问题

1) ThreadLocal需要注意的问题,每次执行完毕后,要使用remove()方法来清空对象,否则 ThreadLocal 存放大对象后,会出现OMM。

2) ThreadLocal要使用static的 ,在其他地方可以直接用get 和 set方法。

另附上一篇分析非常到位的文章链接:http://www.godiscoder.com/?p=479

0 0
原创粉丝点击