ThreadLocal(待补充)

发布时间 2023-04-16 23:30:05作者: 小连同学ya

ThreadLocal的结构

每个线程对象都有一个ThreadLocal.ThreadMap维护了一个ThreadMap;ThreadMap维护了Entry结构的一个数组对象。

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

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

 

ThreadLocal为什么会出现内存溢出的问题

ThreadLocal的key是一个软引用对象。

  • 软引用对象是当发生gc的时候,软引用对象,如果在gc的时候并且没有被引用了,就会被进行回收。如果当前线程ThreadLocal没有被引用了,当gc的时候,就会被回收掉key,但是当前线程还存在着对value的强引用一直无法被回收掉,所以就造成了oom

  • Current Thread Reference --> Current Thread --> ThreadLocalMap --> EntryValue --> Object

 

ThreadLocal为什么要将key设置为弱引用有什么好处

设置为弱引用,gc回收的时候会被回收掉,但是key为null,value不为null的对象没办法被回收掉。所以在ThreadLocal的时候的set,get,remove的时候会回收掉key为value的对象。

  • 如果设置为强引用的话,使用这些方法是没办法进行回收掉的。 分配了ThreadLocal对象,但是并没有执行其get、set、remove方法,导致不能有效的清除null对象;

  • 使用线程池的情况下,使用完ThreadLocal一定要使用remove方法即时清理,因为ThreadLocal是属于某个线程的,而在使用线程池的情况下,这些线程都是可重复利用、存活时间长的线程,如果在使用过程中不仅从即使的remove,那么不仅会造成内存泄露的问题,还会引发一些功能逻辑问题,比如,B请求可能和A请求分配到了线程池中的同一个线程,那么它们拿到的ThreadLocal就是一样的。

为什么value也不设置为弱引用

 

父子线程如何共享变量--InheritableThreadLocal