很多人对于threadlocal都不是很清楚,那么,下文要给大家介绍的就是threadlocal,主要是和threadlocal原理相关的内容,一起来了解一下threadlocal的原理吧。
首先我们要知道threadlocal是一个泛型类,保证能够接受任何类型的对象。
因为,在一个线程当中能够有多个threadlocal对象的存在,所以说,实际上是threadlocal内部维护了一个map,这个map不是直接使用的HashMap,而是threadlocal实现的一个被称作threadlocalmap的静态内部类。
注意,我们使用的get()、set()方法实际上都是调用了这个threadlocalmap类对应的get()、set()方法。
例如:
set方法
public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); }
get方法
public T get() { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) return (T) map.get(this); // Maps are constructed lazily. if the map for this thread // doesn't exist, create it, with this ThreadLocal and its // initial value as its only entry. T value = initialValue(); createMap(t, value); return value; }
createMap方法
void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }
threadlocalmap是个静态的内部类
static class ThreadLocalMap { ........ }
最终的变量,是放在了当前线程的threadlocalmap当中,而不是存在threadlocal上,threadlocal能够理解成,只是threadlocalmap的封装传递了变量值。
下面要讲到的就是内存泄漏问题。
实质上threadlocalmap当中,所使用的key是threadlocalmap的弱引用。
下面来介绍一下弱引用的特点。
假如这个对象只存在了弱引用,那么,在下次垃圾回收时,就一定会被清理掉。
所以,假如说在threadlocalmap并没有被外部强引用的时候,在垃圾回收的时候,就会被清理掉,这样的话,threadlocalmap当中使用的这个threadlocalmap的key特会被清理掉。
可是,value是强引用,不会被清理,这样的话就会出现key为null 的value。
实际上,threadlocalmap的视线当中,已经考虑到了这样的情况,在调用set()、get()、remove() 方法时,会清理掉key为null的记录。
假如,会出现内存泄漏,那么,只有在出现了key为null的记录后,没有手动调用remove()方法,并且,以后也不再调用get()、set()、remove()方法的情况下。
关于threadlocal原理你都了解了吗?更多关于threadlocal的常见问题,请继续关注本站来进行了解吧,希望可以对你有所帮助。
推荐阅读;