• 面试分析:你懂不懂threadlocal?


    目录

    ThreadLocal

    应用场景

    get与set方法

    ThreadLocalMap

    ThreadLocalMap.set

     ThreadLocalMap.get

     ThreadLocalMap.remove

    线程隔离

    内存泄漏


    今天看一个面试题,threadlocal的原理

    首先,要知道threadlocal是什么,如果都不知道这个是什么,那就也别看什么原理了.....

    ThreadLocal

    threadlocal 是线程的内部存储类,可以在指定线程内存储数据,且只有指定线程可以拿到数据

    说白了,就是为了数据安全

    不同的线程在使用 threadlocal 的时候,都会有自己的一个 threadlocalmap 对象,并且通过 threadlocal 进行管理

    每个新线程都会被实例化一个 threadlocalmap,并且赋值给 threadLocals,如果已经存在了 threadLocals,那就直接复用

    应用场景

    那种作用域是线程,并且不同的线程还会有不同的副本的时候,就可以考虑用 threadlocal

    当然,如果说业务处理逻辑强依赖与 副本变量,那可能就不大适合这玩意了

    get与set方法

    这一块我们可以直接看源码就行

    1. public void set(T value) {
    2. Thread t = Thread.currentThread();
    3. ThreadLocalMap map = getMap(t);
    4. if (map != null)
    5. map.set(this, value);
    6. else
    7. createMap(t, value);
    8. }
    1. public T get() {
    2. Thread t = Thread.currentThread();
    3. ThreadLocalMap map = getMap(t);
    4. if (map != null) {
    5. ThreadLocalMap.Entry e = map.getEntry(this);
    6. if (e != null) {
    7. @SuppressWarnings("unchecked")
    8. T result = (T)e.value;
    9. return result;
    10. }
    11. }
    12. return setInitialValue();
    13. }

    可以看到,无论是 get 还是 set,都是用的 ThreadLocalMap 的方法

    ThreadLocalMap

    ThreadLocalMap 为每个 thread 都维护了一个数组 table,threadllcal 确定了一个数组下标,而这个下标是value存储的对应位置

    从之前的 set 源码,我们可以得到,ThreadLocalMap 是一个延迟创建的结构,也就是说,至少要放置一个内容时才会创建

    而通过创建 ThreadLocalMap 的源码,我们可以得到,ThreadLocalMap 初始化时创建了默认长度是16的 Entry 数组。通过 hashCode 与 length 位运算确定索引值 i

    ThreadLocalMap.set

    我们来看看 threadLocalMap 的 set 方法

     ThreadLocalMap.get

    get 方法没有什么可看的,就直接取就完事了

     ThreadLocalMap.remove

    我们再看看 remove 方法

    1. private void remove(ThreadLocal key) {
    2. Entry[] tab = table;
    3. int len = tab.length;
    4. int i = key.threadLocalHashCode & (len-1);
    5. for (Entry e = tab[i];
    6. e != null;
    7. e = tab[i = nextIndex(i, len)]) {
    8. if (e.get() == key) {
    9. e.clear();
    10. expungeStaleEntry(i);
    11. return;
    12. }
    13. }
    14. }

    可以看到,也没什么东西

    线程隔离

    threadlocal 拥有线程隔离特性,只有线程内可以访问

    类比 synchronized,它是通过线程等待来解决访问冲突问题

    而 threadlocal 是通过空间存储来解决访问冲突问题

    内存泄漏

    注意,threadlocal 有一个地方需要注意,那就是内存泄漏的问题,使用完,一定要 remove,否则永远清除不掉,时间长了就会出问题了

  • 相关阅读:
    iOS——UIColor与CGColor与CALayer
    Java —— 数组
    java excel、word、PPT转换成pdf预览
    【带头学C++】----- 1.基础知识 ---- 1.24 逻辑控制语句
    wx.canvasToTempFilePath导出的图片不清晰
    产品开发和制造中,FMEA不起作用的原因及改善方法——FMEA软件
    PMP每日一练 | 考试不迷路-9.21(包含敏捷+多选)
    OpenAI开发者大会:定义未来AI的新功能、愿景和商业版图
    KeyError: ‘mmrotate.RotLocalVisualizer is not in the visualizer registry.
    传输层TCP协议
  • 原文地址:https://blog.csdn.net/weixin_46097842/article/details/126675253