• threadlocal详解


    threadlocal定义:每个线程有自己的数据 其他的线程拿不到

    每个线程本身有一个threadlocals属性(类型是ThreadLocalMap),map中存储的entry的key是当前线程的threadlocal对象,value是自定义的值

     ThreadLocalMap中的静态内部类Entry结构

    static class Entry extends WeakReference<ThreadLocal<?>> {
                // 当前线程关联的threadlocal的value值
                Object value;
           
                Entry(ThreadLocal<?> k, Object v) {
                    super(k);
                    value = v;
                }
            }

    注意entry的key是个弱引用,value是个强引用

    那么为什么entry要设计成弱引用呢?

    threadlocal对象被gc回收的时候 线程的threadlocalmap中相对应的entry的key变为null

    可以区分哪些entry是过期的

    注意:ThreadlocalMap类是静态内部类 是共享的数据

    threadlocalmap放入元素的时候如果发生hash冲突 是不会转化为链表存储的,会向slot后查找可以存放的桶位,查找的时候也是这样

    查找方法最核心的方法是:

     1  private int expungeStaleEntry(int staleSlot) { // 这个方法是用来优化查找 优化过期数据,目的是帮助过期数据让gc回收,让hash冲突的entry找到尽可能正确的位置
       // 执行这个方法的时候说明查找的entry没找到并且key等于null staleSlot代表key为null的索引
    2 Entry[] tab = table; 3 int len = tab.length; 4 5 // expunge entry at staleSlot 6 tab[staleSlot].value = null; 7 tab[staleSlot] = null; 8 size--; 9 10 // Rehash until we encounter null 11 Entry e; 12 int i; 13 for (i = nextIndex(staleSlot, len); 14 (e = tab[i]) != null; 15 i = nextIndex(i, len)) { //查找到entry不为null的索引 16 ThreadLocal<?> k = e.get(); 17 if (k == null) { //key失效了 18 e.value = null; 19 tab[i] = null; 20 size--; 21 } else { 22 // 查到到的entry不是过期数据 23 int h = k.threadLocalHashCode & (len - 1); 24 // 并且就是位置不正确的entry 正确位置是h i是查找出来的entry的当前位置 25 if (h != i) {// h!=i说明位置发生了偏移了 26 // 将entry当前位置设置为null 也就是i设置为null 27 tab[i] = null; 28 29 // Unlike Knuth 6.4 Algorithm R, we must scan until 30 // null because multiple entries could have been stale. 31 // 如果h位置被占用了 就往后查找最靠近正确位置的index 找到就存入数据 32 while (tab[h] != null) 33 h = nextIndex(h, len); 34 tab[h] = e; 35 } 36 } 37 } 38 return i; 39 }

     threadlocal的entry数组中entry的size大于等于数组长度的3分之2进行rehash,扩容rehash前回先清除一下key失效的entry,如果清理过后entry的数量还大于等于threhold的4分之3

    进行数组扩容并重新计算entry的下标

  • 相关阅读:
    双系统卸载linux和装双系统的方法
    linux中使用vim编译C++程序
    存储器管理之页面置换算法
    Python中open文件的各种打开模式
    RAL调用
    分布式系统事务一致性解决方案
    消息队列设计
    nmq消息队列解析
    分布式session的实现
    分布式系统常用思想和技术总结 (入门很清楚)
  • 原文地址:https://www.cnblogs.com/isnotnull/p/13997060.html
Copyright © 2020-2023  润新知