美文网首页
面试官:说说ThreadLocal ,ThreadLocalMa

面试官:说说ThreadLocal ,ThreadLocalMa

作者: 面试君 | 来源:发表于2019-10-09 16:18 被阅读0次

引言

这三种的关系由于大量的内部类的关系,第一次看的时候还是有点绕的,感觉你是老子的孙子,又是老子的老子。我还是建议你先抛开内部类的关系,把每一个类当作普通类来看到,理解每個类的职责,最后再把内部类放进去考虑这样设计的目的。<font style="color:red">这里也给大家一个启示,面对复杂的事情的时候,我们需要跳出来,先把问题简单化,大方向把握了,再进一步去细化每一个功能点和设计的艺术。</font>

关系图解

接下来我们看下面一张图

image

从上图我们可以发现Thread 中持有一个ThreadLocalMap ,这里你可以简单理解为就是持有一个数组,这个数组是Entry 类型的。
Entry 的key 是ThreadLocal 类型的,value 是Object 类型。也就是一个ThreadLocalMap 可以持有多个ThreadLocal。他们是一对多的关系(当然Entry 还涉及到弱引用的技术,这里不展开,不然就没完没了了)

加上内部类的关系

image

为什么ThreadLocalMap 设计为ThreadLocal 内部类

看到各种内部类是不是有点晕,感觉你是老子的孙子,又是老子的老子,为什么不独立ThreadLocalMap 出来呢?其实这里涉及到内部类起到封装的作用。来,我们看看源码的解析

    /**
     * ThreadLocalMap is a customized hash map suitable only for
     * maintaining thread local values. No operations are exported
     * outside of the ThreadLocal class. The class is package private to
     * allow declaration of fields in class Thread.  To help deal with
     * very large and long-lived usages, the hash table entries use
     * WeakReferences for keys. However, since reference queues are not
     * used, stale entries are guaranteed to be removed only when
     * the table starts running out of space.
     */
    static class ThreadLocalMap {
    //这里省略其他属性和方法
    }

主要是说明ThreadLocalMap 是一个线程本地的值,它所有的方法都是private 的,也就意味着除了ThreadLocal 这个类,其他类是不能操作ThreadLocalMap 中的任何方法的,这样就可以对其他类是透明的。同时这个类的权限是包级别的,也就意味着只有同一个包下面的类才能引用ThreadLocalMap 这个类,这也是Thread 为什么可以引用ThreadLocalMap 的原因,因为他们在同一个包下面。

虽然Thread 可以引用ThreadLocalMap,但是不能调用任何ThreadLocalMap 中的方法。这也就是我们平时都是通过ThreadLocal 来获取值和设置值,看下以下代码

public class Test {

    public static void main(String[] args) {
        ThreadLocal<String> local = new ThreadLocal<>();
        local.set("hello word");
        System.out.println(local.get());
    }
}

但我们调用ThreadLocal 的get 方法的时候,其实我们最后是通过调用ThreadLdocalMap 来获取值的

 public T get() {
        //这里通过获取当前的线程
        Thread t = Thread.currentThread();
        //通过线程来获取ThreadLocalMap ,还记得我们上面说的Thread 里面有一个ThreadLocalMap 属性吗?就是这里用上了
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

到这里,读者应该大概明白了,其实ThreadLdocalMap 对使用者来说是透明的,可以当作空气,我们一值使用的都是ThreadLocal,这样的设计在使用的时候就显得简单,然后封装性又特别好。

ThreadLdocalMap 什么时候开始和Thread 进行绑定的呢

在第一次调用ThreadLocal set() 方法的时候开始绑定的,来我们看下set 方法的源码

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
        //第一次的时候进来这里,因为ThreadLocalMap 还没和Thread 绑定
            createMap(t, value);
    }
    
    //这个时候开始创建一个新的ThreadLocalMap 赋值给Thread 进行绑定
    void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

相关文章

  • 面试官:说说ThreadLocal ,ThreadLocalMa

    引言 这三种的关系由于大量的内部类的关系,第一次看的时候还是有点绕的,感觉你是老子的孙子,又是老子的老子。我还是建...

  • 面试官再问你 ThreadLocal,你就这样“怼”回去!

    面试官:说说你对ThreadLocal的理解... 我们该怎么回答???? ThreadLocal用在什么地方? ...

  • Thread、ThreadLocal、ThreadLocalMa

    1 先上一张经典的关系图,完了贴下原始的代码。 纯看代码写的真是挺绕的,先来张图有个整体的印象吧。 对着Thre...

  • ThreadLocal Thread ThreadLocalMa

    前言 ThreadLocal :每个线程通过此对象都会返回各自的值,互不干扰,这是因为每个线程都存着自己的一份副本...

  • ThreadLocal原理解析(2):ThreadLocalMa

    我的CSDN博客同步发布:ThreadLocal原理解析(2):ThreadLocalMap源码解析 转载请注明出...

  • 面试官:说说你对ThreadLocal的了解

    一般有多个孩子的家庭,买玩具都得买多个。如果就买一个,嘿嘿就比较刺激了。这就是避免共享,给孩子每人一个玩具对应到我...

  • 说说ThreadLocal原理?

    ThreadLocal可以理解为线程本地变量,它会在每个线程都创建⼀个副本,那么在线程之间访问内部副本变量就⾏了,...

  • 线程

    1. 问:ThreadLocal了解吗?您能给我说说他的主要用途吗? 答: 从JAVA官方对ThreadLocal...

  • threadlocal跨线程传递解决方案(上)

    1.在面试的过程中。经常会遇到面试官提到threadlocal的问题,很多情况下: 面试官最爱问的是: threa...

  • tcp长链接

    面试官:说说tcp怎么设置成长链接? 我:创建的时候加上keepalive标志。 面试官:嗯,说说tcp是如何保持...

网友评论

      本文标题:面试官:说说ThreadLocal ,ThreadLocalMa

      本文链接:https://www.haomeiwen.com/subject/gcugpctx.html