ThreadLocal
从名字上我们看出,它叫做本地线程变量,每个线程都有各自的的变量,而不再是我们之前的两个线程共用同一个变量;
以这个类创建的变量,在多个线程都用到这个变量时,可以为每一个线程创建一个变量副本,使得多个线程之间这个变量相互隔离,不影响。
如下创建方式:
ThreadLocal底层实现
首先ThreadLocal是一个泛型类,保证可以接收任何类型的对象,底层维护了一个ThreadLocalMap静态内部类,我们调用的get()、set()方法就是它们实现的。
ThreadLocal的Set方法源码实现:
publicvoidset(Tvalue){
Thread t=Thread.currentThread();
ThreadLocalMapmap=getMap(t);
if(map!=null){
map.set(this,value);
}else
creatMap(t,value);
}
过程:先拿出调用set方法的线程,然后取出这个线程内部的副本变量,由ThreadLocalMap存储,如果不为空,说明之前已经加过值,通过ThreadLocalMap的set方法进行赋值,将原来的value换成新的即可。
如果为空,那么先为这个线程创建一个变量副本ThreadLocalMap,然后ThreadLocal作为键,存入的数作为值,存储即可
注:为每个当前线程创建一个threadLocalMap,唯一的ThreadLocal对象作为key,set存入的值为value。
ThreadLocal内存泄漏问题
因为ThreadLocal与弱引用有关,key失效后,value还被强引用着,造成内存泄漏。正确的用法,用完之后,及时调用remove()清除
普及一下对象引用在垃圾回收时具有的的状态
引用的四个状态
后面三个是为了要对垃圾对象进行标志
对象引用的四个状态,这三个引用也都是用来标记对象的一种状态;
当一些对象成为垃圾后,还需要不同的状态,可以继承与oftReference、WeakReference、PhantomReference或者把自己的对象添加到软、弱、虚的对象中.
强引用
即对象是有引用指向的,默认的引用类型Object obj=new Object();这种情况下new出来的对象是不能被垃圾回收的,只要强引用关系还存在,垃圾收集器就永远不会回收掉。被引用的对象区别于软引用、弱引用、虚引用
软引用
已经成为垃圾的对象
内存充足的情况下,可以保留软引用对象;垃圾回收时,内存不够即回收;
软引用是用来描述一些还有用,但并非必需的对象
我们也可以通过方式让创建出的对象成为软引用
弱引用
弱引用管理的对象,只能存活到下一次垃圾回收
虚引用
若一个对象仅仅持有虚引用,那么和没有引用几乎是一样的,随时会被垃圾回收器回收。
设置虚引用的唯一目的就是被收集其回收时收到一个系统通知。
总结:这几种状态都是用来描述对象的,软弱虚三种状态的前提都是,对象已经成为垃圾,但是因为有了这个状态的加持,不会立即回收,而是满足每种状态的条件才会进行回收。
对象引用一般有五种状态:强引用(即对象是有引用指向的)、软引用、弱引用、虚引用、普通的失去引用的对象(与虚引用的区别是少了被回收时的系统通知)