Android之ThreadLocal笔记

ThreadLocal线程本地变量(副本)——不能用Map代替,因为这样所有线程又会去争夺Map资源,未解决根本问题

 

多个线程执行时,为了互不干扰资源,因此用到了ThreadLocal。

 

原理:Thread类里面有一个成员变量ThreadLocalMap,而ThreadLocalMap类里有成员变量entry数组,当我们用ThreadLocal.set值得时候,实际上就是往entry数组添加内容,而entry数组又只属于该线程(Thread)独有的成员变量,因此就可以做到数据在线程之间的相互隔离。存入entry的值是键值对的形式存在,key为ThreadLocal,value是存入的值,因此当线程需要让多个数据隔离的时候,需要new出多个ThreadLocal对象,并存入entry数组。

 

 

 

 

ThreadLocal如何引起内存泄漏?如何避免?

 

我们知道,当我们往entry数组里面set ThreadLocal的时候是以键值对的形式存放的,threadlocal为key,存放的需要进行线程隔离的值为value,而源码里面ThreadLocal是弱引用

这就表明在gc执行垃圾回收的时候ThreadLocal会被回收,也就是Map中的某个key会为null,此时该map已经无法通过key取到被回收的threadlocal所对应的value,然而map又指向了该value

因此该value不会被回收,该内存区域依然被占据,因此造成内存泄漏。

当然,ThreadLocal会在get和set的时候进行查询,如果发现key被回收了,那么会清理value,因此value也不是无限增长的情况。

所以,当我们线程执行完毕之后,如果用到了ThreadLocal,那么要在最后添加ThreadLocal.remove();这样就能保证当value被回收。

 

 

 

  • 强引用:普通的引用,强引用指向的对象不会被回收;
  • 软引用:仅有软引用指向的对象,只有发生gc且gc之后内存还是不足,才会被回收;
  • 弱引用:仅有弱引用指向的对象,只要发生gc就会被回收。
posted @ 2020-11-28 11:58  金大人的梦  阅读(123)  评论(0编辑  收藏  举报