美文网首页
高并发编程之ThreadLocal

高并发编程之ThreadLocal

作者: Insecurity | 来源:发表于2021-01-17 19:21 被阅读0次

    强软弱虚

    1.普通引用,对象引用(被回收时,会调用finalize 方法)
    2.软引用
        a.设置 -Xmx20M  设置堆内存最大为20M
        b.SoftReference<byte[]> 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<ThreadLocal<?>>
    

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

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

    相关文章

      网友评论

          本文标题:高并发编程之ThreadLocal

          本文链接:https://www.haomeiwen.com/subject/ctqzaktx.html