简单分析 ThreadLocal
ThreadLocal 可简单理解为 Thread 的局部变量,在线程的生命周期内起作用。
ThreadLocal 原理
ThreadLocal 类的内部有 ThreadLocalMap内部类,Entry 又是 ThreadLocalMap 类里的内部类。
ThreadLocalMap 是一个为 ThreadLocal 提供服务的 “customized hash map” 。
Entry 是一个继承 WeakReference 的类,是 ThreadLocalMap 的构成类型,Entry 的中的 key 即为 ThreadLocal。
Thread 类里声明了 ThreadLocalMap。
1 | /* ThreadLocal values pertaining to this thread. */ |
接下来分析下 ThreadLocal 类的代码 (Android SDK 25)
1 | public T get() { |
除此之外的 set
、createMap
、getMap
等的方法都是些常见 HashMap 的操作。
ThreadLocal 使用不当造成的内存泄漏
因为 ThreadLocalMap 使用 ThreadLocal 的弱引用作为 key,所以当系统 GC ,ThreadLocal对象被回收,ThreadLocalMap 中就会有 key 为空的 Entry,这个 Entry 的 value 就没法访问了,要是线程由于种种原因没有结束的话(譬如作为线程池的一员),那么 key 为空的 Entry 中的 value 由于被强引用 Thread Ref -> Thread -> ThreadLocalMap -> Entry -> value
导致没法被回收,造成内存泄漏。
那么需要怎么做来避免泄漏呢?
其实当调用 ThreadLocal 的 get
、 set
、 remove
的时候都会调用到 ThreadLocalMap 里的方法将 key 为空的 Entry 的 value 置空。
所以正确的做法是在用完 Threadlocal 后,都调用 remove
方法来清除数据。