ThreadLocal详解
本文最后更新于156 天前,其中的信息可能已经过时,如有错误请发送邮件到3368129372@qq.com

组成

ThreadLocal->ThreadLocalMap
->Entry1(key(ThreadLocal类型), value),Entry1(key(ThreadLocal类型), value)... ...

ThreadLocalMap类似于哈希map,线性探测法解决冲突,实现为

static class ThreadLocalMap {
  private static final int INITIAL_CAPACITY = 16;
  private Entry[] table;
  private int size = 0;
  private int threshold;

  private void setThreshold(int len) {
      this.threshold = len * 2 / 3;
  }

  private static int nextIndex(int i, int len) {
      return i + 1 < len ? i + 1 : 0;
  }

  private static int prevIndex(int i, int len) {
      return i - 1 >= 0 ? i - 1 : len - 1;
  }

  ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
      this.table = new Entry[16];
      int i = firstKey.threadLocalHashCode & 15;
      this.table[i] = new Entry(firstKey, firstValue);
      this.size = 1;
      this.setThreshold(16);
  }

  private ThreadLocalMap(ThreadLocalMap parentMap) {
      Entry[] parentTable = parentMap.table;
      int len = parentTable.length;
      this.setThreshold(len);
      this.table = new Entry[len];
      Entry[] var4 = parentTable;
      int var5 = parentTable.length;

      for(int var6 = 0; var6 < var5; ++var6) {
          Entry e = var4[var6];
          if (e != null) {
              ThreadLocal<Object> key = (ThreadLocal)e.get();
              if (key != null) {
                  Object value = key.childValue(e.value);
                  Entry c = new Entry(key, value);

                  int h;
                  for(h = key.threadLocalHashCode & len - 1; this.table[h] != null; h = nextIndex(h, len)) {
                  }

                  this.table[h] = c;
                  ++this.size;
              }
          }
      }

  }

内存泄漏问题

  1. ThreadLocal的实现为

    static class Entry extends WeakReference<ThreadLocal<?>> {
        Object value;
    
        Entry(ThreadLocal<?> k, Object v) {
            super(k);
            this.value = v;
        }
    }

    可见key(即ThreadLocal)对象为弱引用。因为Thread能到达ThreadLocal,而Thread可能被线程池复用而长时间不销毁。因此需要改为弱引用,只存在弱引用时只要GC就被回收。
    注:一般ThreadLocal作为某个类的成员变量而被强引用,这个类销毁时说明强引用消失,马上被GC)

  2. 为什么value不设成弱引用呢?因为value不会被作为成员变量而强引用,直接回收会导致ThreadLocal还在但是对应的值已经消失了!!!
  3. 在调用get方法时会检测对应的ThreadLocal(key)是否还存在,无则回收value值。
  4. 内存泄漏的情况:未使用remove(),且set()后未get()回收value,且线程被复用,Thread对象一直存在时。
感谢您的收看~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇