高并发编程之ThreadLocal

强软弱虚

1.普通引用,对象引用(被回收时,会调用finalize 方法)
2.软引用
    a.设置 -Xmx20M  设置堆内存最大为20M
    b.SoftReference m = new SoftReference<>(new byte[1024*1024])
    c.此时创建一个强引用,1024*1024*20 
    d.此时m对象会被回收
3.弱引用
    a.WeakReference,只要一执行GC就回收了,能get到, 一次性消费。
4.虚引用NIO,用于提高效率,实现zero copy)
    a.PhantomReference,get不到, 管理堆外内存。
    b. jvm中的堆内存会有一块内存,指向堆外内存(
    c.过程:虚引用被回收时,会被放入到一个队列中,GC发现queue中有新值了,则会处理堆外内存(属于操作系统的内存)

ThreadLocal

概念:线程本地内存。(仅仅和当前线程相关,其他线程无法获取)
举例:spring 的@Transactional 注解,必须保证 两个内部方法是同一个连接。
分析过程:Thread 对象,中有一个属性 ThreadLocal.ThreadLocalMap,当执ThreadLocal 对象的get方法时,实际上是将ThreadLocal 对象的hascode作为key  对象值作为value,存放在ThreadLocal.ThreadLocalMap属性中。其中key为weak引用,是为了保证 ThreadLocal.ThreadLocalMap属性不指向ThreadLocal  对象时,可以直接被回收。
源码如下:(其实就是一个map  key为当前线程)
//Thread 类,ThreadLocalMap  属性
 ThreadLocal.ThreadLocalMap threadLocals = null;

//Thread的静态内部类,(用于存放ThreadLocal变量)
static class ThreadLocalMap
    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();
    }
  //如果为空,则创建一个ThreadLocalMap,并设置给 Thread 的threadLocals 属性
  void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

//ThreadLocalMap 的Entry 使用的是WeakReference 引用
//key 是 ThreadLocal对象引用(每个线程都是)当 每个线程都有自己的ThreadLocalMap
static class Entry extends WeakReference>

为什么Entry 的key 使用的是弱引用?

1.当thread tl 指向 为空时, ThreadLocal对象 需要被回收,如果ThreadLocalMap 中的key为强引用的话,这不会被回收
2.ThreadLocalMap被回收时,ThreadLocalMap  的key为null,如何回收ThreadLocalMap 中的记录呢,调用  remove方法
必须remove,才能删除 ThreadLocalMap中的值。
image.png

你可能感兴趣的:(高并发编程之ThreadLocal)