ThreadLocalMap 源码分析

x33g5p2x  于2021-12-25 转载在 其他  
字(1.5k)|赞(0)|评价(0)|浏览(319)

一 点睛

在分析 ThreadLocal 方法的时,我们了解到 ThreadLocal 的操作实际上是围绕 ThreadLocalMap 展开的。所以,我们有必要分析一下 ThreadLocalMap 的源码。

二 基本结构

ThreadLocalMap 是 ThreadLocal 的内部类,没有实现 Map 接口,它是用独立的方式实现 Map 的功能,其内部的 Entry 也是独立实现。

该结构图对于源码如下。

static class ThreadLocalMap {
    /**
     * The entries in this hash map extend WeakReference, using
     * its main ref field as the key (which is always a
     * ThreadLocal object).  Note that null keys (i.e. entry.get()
     * == null) mean that the key is no longer referenced, so the
     * entry can be expunged from table.  Such entries are referred to
     * as "stale entries" in the code that follows.
     */
    static class Entry extends WeakReference<ThreadLocal<?>> {
        /** The value associated with this ThreadLocal. */
        Object value;

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

三 成员变量解读

/**
* 初始容器 -- 必须是 2 的整次方
*/
private static final int INITIAL_CAPACITY = 16;

/**
* 存放数据的 table, 必要时会扩容.
* 数组的长度必须是 2 的整次方.
*/
private Entry[] table;

/**
* 数组里面 entry 的个数,可以判断 table 当前使用量是否超过阀值
*/
private int size = 0;

/**
* 进行扩容的阀值,表使用量大于它的时候进行扩容
*/
private int threshold; // 默认为 0

和 HashMap 类似,INITIAL_CAPACITY 代码这个 Map 的初始容量,table 是一个 Entry 类型的数组,用于存储数据,size 代表表中存储数目;threadhold 代表需要扩容时对应 size 的阀值。

三 存储结构 Entry 的解读 

/**
* Entry 继承 WeakReference, 并且用 ThreadLocal 作为 key
* 如果 key 为 null,意味着 key 不再被引用
* 因此这时候 entry 也可以从 table 中清除
*/
static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

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

在 ThreadLocalMap 中,也是用 Entry 来保存 K-V 结构数据的,不过 Entry 中的 key 只能是 ThreadLocal 对象,这点在构造方法中已经写死了。

另外,Entry 继承 WeakReference,也就是 key(ThreadLocal)是弱引用,其目的是将 ThreadLocal 对象的生命周期和线程生命周期解绑。

相关文章