ThreadLocal能用来做什么
保证在ThreadLocal中保存的对象,在同一个线程中获取到的是同一个实例。
如:spring-Transaction中的connetcion对象,hibernate-session对象及mybatis-session对象。
例如:
1 | import java.io.IOException; |
总结:同一个线程中获取到的是同一个对象,其他线程获取不到。
不使用的对象要调用remove方法删除掉。
源码分析
java.lang.ThreadLocal#set方法
1 | public void set(T value) { |
调用向ThreadLocal set(value)时,是将value放入当前线程对象的currentThread#
threadLocals(ThreadLocal.ThreadLocalMap类型)变量中了。
接着看ThreadLocalMap#set方法的实现
1 | static class ThreadLocalMap { |
以Entry<threadLocal对象, value>方式放进ThreadLocalMap。
对象引用
强引用(普通new对象)
1 | public class D{ |
1 | public class T1_CommonReferenceTest { |
总结:d对象一直会存在,只有当对象引用被删除时,gc才会回收空间
SoftReference软引用
1 | import java.lang.ref.SoftReference; |
总结:当堆空间不足时,gc会自动回收软引用对象;
所以,SoftReference对象适合来做缓存。
WeakReference弱引用
1 | import java.lang.ref.WeakReference; |
总结:gc会自动回收不再使用的弱引用对象。
对比ThreadLocal中,如果不是弱引用对象的话,可能会导致内存泄露。
PhantomReference虚引用
1 | import java.io.IOException; |
总结:phantomReference.get()是一致为空的,说明在jvm内存中是一直获取不到的。
作用:用来管理堆外内存的。
如NIO中DirectByteBuffer对象,使用的是堆外内存;
由专门的gc线程负责监视ReferenceQueue并销毁。