ThreadLocal相关内容解读
1.JAVA中的引用类型有哪几种?
强引用,软引用,弱引用,虚引用
2.每种引用类型的特点是什么?
强引用:这个对象只要还没有被垃圾回收器回收,那么永远都会存在
软引用:这个对象,只要内存空间还足够,那么就不会被回收,如果内存空间不足,那么就会被回收
弱引用:这个对象无论内存空间是否重组,只要进行垃圾回收,那么就会被回收。
虚引用:没有实际作用,只能在垃圾回收时给你一个提示。
3.每种引用类型的应用场景是什么?
强引用:就是我们常见的new
软引用:用来做一些缓存
弱引用:ThreadLocal就是典型代表
虚引用:用以控制直接内存
1.1 强引用
就是创建一个对象,,并把这个对象赋给一个引用变量。
我们需要知道,如果对象是被强引用的话,只要还没有被垃圾回收器回收,那么它就一直存在。
Object o =new Ojbect();
String str = "hello,world";
1.2 软引用
如果一个对象具有软引用,内存空间如果足够, 垃圾回收器就不会回收它。但是如果内存空间的内存不足了, 就会回收这些对象的内存。
我们通常使用软引用做一些高速缓存,如网页缓存、图片缓存等。
MyObject ref = new MyObject();
SoftReference aSoftRef = new SoftReference(ref);
这时对于这个MyObject对象,有两个引用路径,一个是强引用,一个是弱引用。我们可以结束这个实例的强引用
ref = null
这时,这个MyObject对象就成了软引用对象。
1.3 弱引用
弱引用也是用来描述非必需对象的,当jvm进行垃圾回收时,
无论内存是否充足,都会回收被弱引用关联的对象。
WeakReferece<People> reference = new WeakReference<People>(new People("lala");
class People{
public String name;
public int age;
public People(String name,int age){
this.name = name;
this.age = age;
}
@Override
public String toString(){
return "[name:"+name+",age:"+age+"]";
}
}
1.4 虚引用
虚引用和前边的三种引用不同,它并不影响对象的生命周期。
它只有一个作用,就是用以管理直接内存。
4.ThradLocal你了解吗?
通过下边这段代码我们可以知道,两个线程
一个用以设置线程值,
一个用以获取线程值,最后却无法获取设置了的值,
这就告诉我们线程变量是隔离的,所以我们才会使用ThreadLocal这个东西。
public class ThreadLocal2 {
static ThreadLocal<Person> tl = new ThreadLocal<>();
public static void main(String[] args) {
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(tl.get());//最后的执行结果为null
}).start();
new Thread(()->{
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
tl.set(new Person());
}).start();
}
static class Person{
String name = "miaozesheng";
}
}
这里我们查看set方法的源码发现,我们会将person放入一个map中,
但是这里的this说明了一个问题,虽然是tl.set,但是实际做的却是
tl是key,person是value,将这两个东西放入到一个map中,
这点对于我们理解ThreadLocal特别重要。
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
5.ThreadLocal应用在什么地方
ThreadLocal经常用在Spring框架中和数据库有关的地方,比如一个数据库的连接,我们用事务控制它的时候,
我们无法让它随意传递,那么这里我们就会用到threaLocal。
6.ThreadLocal会产生内存泄漏你了解吗?
我们这里首先对ThreadLocal做一个简单的总结:
首先线程会new一个tl出来,那么tl会指向一个ThreadLocal,此时的Thread会有一个自己map,
map的key就是tl,map的value就是你要存入的值,此时map的key和tl的关系就是一个弱引用。这里的内存泄露可能存在两个地方,
第一个是ThreadLocal,第二个则是value指向的内存空间。
对于第一个内存泄露,我们可以通过将key和ThreadLcoal之间设为弱引用,那么就可以解决。
对于第二个内存泄露,我们则可以调用map中的remove方法,来释放内存,防止内存泄露。
7.你知道什么叫内存泄露,什么叫内存溢出吗?
内存泄露:内存泄露一般是指程序申请内存时,其它程序占用的内存一直没有进行释放,导致系统没有足够的内存资源用来分配,那么就会造成内存泄露。我们也可以理解为,不再被使用的对象占用的内存没有被释放,就是内存泄露。
内存溢出:内存泄露次数过多,就会造成内存溢出。