哪些地方使用到了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());

1655189175068

弱引用

只要通知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());
   }

虚引用

不会决定对象的生命周期