如果一些变量只有线程自己访问,那么就可以使用ThreadLocal,这是一种通过线程封闭来实现线程安全的一种方式。ThreadLocal的用法跟HashMap非常像,一个set/get,还有一个initialValue方法,使用非常简洁。
可以将其想象成Map,但多少有点不同。比如
HashMap是key-->value,但ThreadLocal是这样的(Thread,ThreadLocal)-->value,我们使用中Thread是不需要指定的,这是ThreadLocal做的事。
事实上,每个Thread对象内部都有个Map对象inheritableThreadLocals,这个对象很像HashMap,虽然它的实现跟HashMap不一样。所以,ThreadLocal的get/set工作相当于:
1. 取得Thread.currentThread()的inheritableThreadLocals
2. 接下来就是对inheritableThreadLocals的get/set了。其中key为ThreadLocal本身
仔细想想,这确实是个非常棒的封装。
一. 是否内存泄露
ThreadLocal的内存引用关系可用如下图表示:
这里有5个对象,ThreadLocal、Thread对象、线程内部Map、Map内部实体Entry、value对象。
这里可能存在问题的是
ThreadLocal对象,因为有很多线程的内部key指向它,若有一个线程一直没退出,那么该
ThreadLocal会不会一直不释放呢?当然是不会,只有ThreadLocalRef为null,ThreadLocal就有可能被回收。因为线程的内部key是一个弱引用。
1. 强引用:普通引用,只要有强引用指向对象,对象就不会被回收
2. 软引用:只被软引用指向的对象,在内部不够时,也会被回收
3. 弱引用:GC扫描到就被回收
4 虚引用:如字面意思,该引用形同虚设。配合引用队列使用,当一个将要被回收的对象有虚引用时,会将该对象加入
引用队列,从而在回收前做一些工作
阅读(1103) | 评论(0) | 转发(0) |