ThreadLocal学习(四)
了解了ThreadLocalMap之后,里面出现了一个名词 “弱引用” ,那么为什么要将这个设置为弱引用而不是设置成强引用呢?
其实主要是因为内存泄露问题,看下面这张图就知道了:
如果是为强引用的话:
当ThreadLocalRef不再使用ThreadLocal对象并且CurrentThread依然运行情况下,始终有强引用链
CurrentThreadRef—>CurrentThread—>ThreadLocalMap—>Entry—>ThreadLocal,导致Entry(包含ThreadLocal,Value)不会被回收,出现内存泄漏。
如果是为弱引用的话:
当ThreadLocalRef不再使用ThreadLocal对象并且CurrentThread依然运行情况下,还是始终有强引用链
CurrentThreadRef—>CurrentThread—>ThreadLocalMap—>Entry—>ThreadLocal,导致Entry(包含Value。ThreadLocal由于是弱引用会被直接回收)不会被回收,出现内存泄漏。
那么以上两种都会导致内存泄漏,那为什么还要使用弱引用呢?
事实上,ThreadLocalMap中的ser/getEntry方法中,会对key为null(也就是ThreadLocal)进行判断,如果为null的话,那么是会对value置为null的。
也就相当于用完ThreadLocal,CurrentThread依然运行情况下,就算忘记调用remove方法,弱引用的ThreadLocal会被回收,对应的value在下一次set,get,remove中任意方法执行时被清除,避免内存泄露,不过,最好还是在使用完ThreadLocal后使用remove方法。