threadLocals

在这里插入图片描述

最近学了学threadLocal
首先第一java中的引用类型 分为强软弱虚
强引用就是Object c =new Object() 强引用,不会被回收,只要有引用指向就不会被回收,即使报OOM也不会被回收
软引用 

在这里插入图片描述

软引用
即对象的软引用。如果一个对象具有软引用,内存空间足够,垃 圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用做缓存。使用软引用能防止内存泄露,增强程序的健壮性 一般用于做缓存
SoftReference<byte[]>m=new  SoftReference<>(new byte[10*1024*1024]);

在这里插入图片描述

弱引用      WeakReference<M> m=new  WeakReference<M>(new  M());
gc来一次清一次

在这里插入图片描述

虚引用不太了解 也没有听明白

在这里插入图片描述

我们想下如果我们有一个变量X 此时需要把这个x通过方法一层一层传过来,但是有些时候,某些类库是传不过来的,
@Transtanct如果这个方法想支持事务 他必须要拿到数据库连接connection
呢么这个connection怎么传过来,绝对不能说和之前的connection不一样
他把这个connection 放到threadLocal,
一定是说每一个线程调用这一套过程用的connection必须是同一个connection
testDemo
 static ThreadLocal<Person> t1=new ThreadLocal<>();
{
    
    
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(t1.get());
        });
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            t1.set(new Person());
        });
    }
  t1.set(new Person());
  当我们点击进去set的时候
    public void set(T value) {
    
    
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
    //  拿到当前线程,也就是说 我们   t1.set(new Person());的时候实际上是把t1为key,new Person 作为value 存入的 一个map中

在这里插入图片描述

我们再来看这个map , t.threadLocals;  他这个map其实是调用了线程的 threadLocals
 ThreadLocal.ThreadLocalMap threadLocals = null;
 也就是说每一个线程都有自己独立的   threadLocals 
也就是说 当我们    t1.set(new Person()); 的时候实际上是调用了当前线程的   threadLocals .set()//并且此时是以 tl[threadLocal对象为key],new Person() 为value 的

在这里插入图片描述

我们再来看看这个    tab[i] = new Entry(key, value);

 static class Entry extends WeakReference<ThreadLocal<?>> {
    
    
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
    
    
                super(k);
                value = v;
            }
        }

在这里插入图片描述

他此时在构造这个Entry 的时候,将我们的t1 设置成为了虚引用

在这里插入图片描述

也就是说当我们调用了  t1.set(new Person()); 的时候
实际上是调用了当前线程的threadLocals.set(tl,new Person())// 把这个threadLocal对象作为Key,new Person作为value, 然后将threadLocal 作为一个弱引用

在这里插入图片描述
在这里插入图片描述

 但是当此时是一个弱引用的时候 gC来一次清理一层,对于hashmap
 当你的key 为null的话 你此时要把这个value或者说这一条数据给remove了,
  假如这个线程是在线程池中 线程中的threadLocals没有被清理掉
清空threadLocals【map】

猜你喜欢

转载自blog.csdn.net/weixin_43689953/article/details/116908765
今日推荐