哪些地方使用到了ThreadLoal(应用场景)
- spring的事物
- aop,lcn的事物源码
模版方法设计模式-提供一个共同的骨架,在父类。子类实现。
httpreques,对象。springmvc-select缓存在当前的线程中。
ThreadLoal 与synchronized的区别
ThreadLoal可以保证线程安全,是以空间换时间的方式解决(添加缓存)
ThreadLoal 底层原理
ThreadLoal 是基于map(ThreadLocalMap,k是线程,v是数值),使用entry封装
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
public T get() {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null) {
ThreadLocalMap.Entry e = map.getEntry(this);
if (e != null) {
@SuppressWarnings("unchecked")
T result = (T)e.value;
return result;
}
}
return setInitialValue();
}
ThreadLoal为什么会引导内存泄露
每个线程当中都会定义一个threadlocalmap对象,有可能把threadlocal变为null.并不一定gc被释放了。
ThreadLocal<String> stringThreadLocal = new ThreadLocal<>();
stringThreadLocal.set("1");
stringThreadLocal=null;
Thread thread = Thread.currentThread();
System.out.println(thread);
如何防御 ThreadLoal内存泄露
每次在做set方法的时候,会清楚之前的key为null
什么叫内存泄露?
表示程序员申请了内存,但是一直没释放。
什么叫内存溢出?
申请内存时,发现内存不存,报错内存溢出。
谈谈你对ThreadLoal的理解
提供线程本地的变量,保证了变量属于当前线程,每个线程都保存了一个副本变量。提供给我们每个线程缓存局部变量。
强 软 弱 虚引用 区别
强引用
就算堆内存溢出了,也不会清理内存
//强引用
Object o1 = new Object();
Object o2=o1;
System.gc();
o1=null;
System.out.println(o1);
System.out.println(o2);
软引用
堆内存空间充足,就不回收。空间不充足,就回收
Object o1 = new Object();
//软引用o1
SoftReference<Object> objectSoftReference = new SoftReference<>(o1);
System.out.println(o1);
System.out.println("软引用对象"+objectSoftReference.get());
o1=null;
byte[] bytes = new byte[30*1024*1024];
System.out.println(o1);
System.out.println("软引用对象"+objectSoftReference.get());
弱引用
只要通知jvm,都会清理该对象
public static void main(String[] args) {
Object o1 = new Object();
//软引用o1
SoftReference<Object> objectSoftReference = new SoftReference<>(o1);
System.out.println(o1);
System.out.println("软引用对象"+objectSoftReference.get());
o1=null;
System.gc();
// byte[] bytes = new byte[30*1024*1024];
// System.out.println(o1);
System.out.println("软引用对象"+objectSoftReference.get());
}
虚引用
不会决定对象的生命周期