ThreadLocal

软引用

1.对象回收是可以跟踪的,finallize()方法

对象被回收时,会调用finallize方法

2.System.in.read()//阻塞main线程,给垃圾回收线程时间执行

①main线程退出,垃圾回收线程也随即退出,可能对象未回收玩,就已退出

②③

3.变量只能是强引用,要想软引用,得变量–>软(逻辑中的软)引用对象–>堆中对象

SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * SoftReference<byte[]> m = new SoftReference<>(new byte[1024 * 10])

4.软引用其实非常简单(堆总共20M,先new 10M软 ,再new 15M强)

内存不够时,会被回收,内存够时会回收。(垃圾回收一次后,任然不够,回收软引用指向的内存)

5.强引用,宁可溢出,也不会回收你

6.软引用有什么用:非常适合来做缓存(内存够的话先在里面呆着)

弱引用

WeakReference<M> m = new WeakReference<>(WeakReference<M> m = new WeakReference<>(new M());

虚引用(NIO NETTY)

作用:管理直接内存

直接内存:JVM可以通过一个指针访问操作系统内存,如果从网络来的数据,就不用再拷贝一份了。

ThradLocal

1.Spring中多个方法嵌套调用,都要支持事务,那么数据库连接对象得是同一个

数据库连接对象不能是不同的,不能是全局的,全局的话就只有1个连接了。

Spring怎么传连接对象的,通过ThreadLocal

2.demo不同线程访问共享的静态变量 ThreadLocal,1个线程放入的,另一个线程取不出来

和线程绑定的,不同线程间隔离。

3.上面的原理,分析源码

每1个线程对象中都有1个ThreadLocalMap类的成员变量,指向一个map

ThreadLocal的set方法是以自己的引用为key,参数为value,存入当前线程的ThreadLocalMap中

Entry是理解的关键,是ThreadLocal的静态内部类,是WeakReference的子类

image-20200503123723708

ThreadLocalMap的get 和set 会remove所有key为null的Entry,还需要手动remove Entry吗?

要的,因为有服务器线程7 * 24 运行,可能不执行get,set方法,这样做可以防止Entry内存泄露。

  • 如果是线程池的话,线程用完,要清除threadlocal. 以防下次用时,可能用的是旧值。

image-20200503124758577

强引用:默认的。

软引用:缓存;

弱引用:防内存泄露

虚引用:jvm管理直接内存用的

ThreadLocal如何使得一个线程只有1个Looper?

1.Looper是如何创建的?

Looper.prepare();

public final class public final class Looper {
  static final ThreadLocal sThreadLocal = new ThreadLocal();
   private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }
}

2.不同线程访问共享静态变量sThreadLocal,调用set方法,以共享的ThreadLocal类的对象的引用为key,以new的Looper对象对Value。它是往当前线程的ThreadLocalMap中存入key,value的;

不同线程通过get取时,拿到的是自己线程的Looper

3.多线程访问共享静态变量sThreadLocal, 1个线程存的东西,另一个线程取不到,起到了线程隔离的作用。

4.ThreadLocalMap中有一个Entry数组,key为什么要继承自弱引用呢?

因为sThreadLocal至空之后,线程Entry的属性key任然持有ThreadLocal的引用,value也不能释放。会有内存泄露的问题

ThreadLocal的作用主要是做数据隔离,填充的数据只属于当前线程,变量的数据对别的线程而言是相对隔离的,在多线程环境下,如何防止自己的变量被其它线程篡改。

https://www.zhihu.com/question/341005993


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!