内部原理
每个线程内部都会维护一个自己的ThreadLocalMap,每个ThreadLocal对象对应一个value值,存在其所在线程的ThreadLocalMap中。
get怎么保证每个线程获取的值不一样?
ThreadLocal的get方法里,会先寻找当前自己所在线程中的ThreadLocalMap对象,然后从该对象中查找当前自己ThreadLocal对象所对应的value进行返回。所以这样就保证了每个线程get出的值不一样。
ThreadLocal 中什么时候回收value,会存在内存泄露吗?
ThreadLocalMap中保存一个Entry对象数组,Entry继承自弱引用,传入ThreadLocal作为弱引用修饰的对象,同时当前Entry对象中保存了value。当ThreadLocal对象回收后,由于弱引用机制,Entry中的key为NULL,后续其他ThreadLocal调用方法set,get或remove时候会触发回收机制,key为NUll的Entry会被回收。
但是,如果key为NULL后,此时不存在其他的ThreadLocal对象了,或者其他的ThreadLocal对象并不调用这些方法,那么在线程存活的情况下,key为null对应的value就一直得不到回收,此时造成了内存泄露。
Looper怎么保证每个线程有自己的looper
对于每个线程调用looper.preapre的时候,prepare方法中都会通过ThreadLocal机制,新生成一个looper对象,保存到当前线程中,后续每次调用looper时候,都是通过ThreadLocal来获取当前线程中的looper。
需要注意的是,
- 主线程的looper是额外保存在looper中的。
- 如果当前线程没有调用Looper.preapre,那么当前线程是不会存在looper对象的