文档章节

java.lang.ThreadLocal 原理探究

OSC知行合一
 OSC知行合一
发布于 2017/04/10 22:52
字数 409
阅读 60
收藏 0

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

java.lang.ThreadLocal 能做到将指定的某个对象和 currentThread 进行绑定,个人好奇心比较强,来研究一下这个功能是如何实现的。

java.lang.Thread 源码: 源码中看到 Thread 对象中会有 ThreadLocalMap 这种类型的属性。

/* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;

    /*
     * InheritableThreadLocal values pertaining to this thread. This map is
     * maintained by the InheritableThreadLocal class.
     */
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

 

java.lang.ThreadLocal 源码 : ThreadLocalMap 是 Thread 中的 static 内部类,从 ThreadLocalMap 的构造方法能看出 ThreadLocalMap 内部操作的是 Entry 对象 , Entry 是 ThreadLocalMap 中的 static 内部类。

/**
         * Construct a new map initially containing (firstKey, firstValue).
         * ThreadLocalMaps are constructed lazily, so we only create
         * one when we have at least one entry to put in it.
         */
        ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
            table = new Entry[INITIAL_CAPACITY];
            int i = firstKey.threadLocalHashCode & (INITIAL_CAPACITY - 1);
            table[i] = new Entry(firstKey, firstValue);
            size = 1;
            setThreshold(INITIAL_CAPACITY);
        }

        /**
         * Construct a new map including all Inheritable ThreadLocals
         * from given parent map. Called only by createInheritedMap.
         *
         * @param parentMap the map associated with parent thread.
         */
        private ThreadLocalMap(ThreadLocalMap parentMap) {
            Entry[] parentTable = parentMap.table;
            int len = parentTable.length;
            setThreshold(len);
            table = new Entry[len];

            for (int j = 0; j < len; j++) {
                Entry e = parentTable[j];
                if (e != null) {
                    @SuppressWarnings("unchecked")
                    ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
                    if (key != null) {
                        Object value = key.childValue(e.value);
                        Entry c = new Entry(key, value);
                        int h = key.threadLocalHashCode & (len - 1);
                        while (table[h] != null)
                            h = nextIndex(h, len);
                        table[h] = c;
                        size++;
                    }
                }
            }
        }

java.lang.ThreadLocal.ThreadLocalMap.Entry 源码 : 看到 Entry extends WeakReference<ThreadLocal<?>>  , 注意这里的泛型类型和 Entry 的构造函数中都是 ThreadLocal 的实例对象 

/**
         * 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;
            }
        }

最后其实真相是:

             

 

© 著作权归作者所有

上一篇: ZooKeeper - Overview
OSC知行合一

OSC知行合一

粉丝 71
博文 124
码字总数 89052
作品 2
东城
程序员
私信 提问
关于本博客数据仓库方面的原创文章汇总

关于本博客数据仓库方面的原创文章汇总 收藏 关于数据仓库方面的文章汇总 我的数据仓库之路! 关于数据仓库维度处理的系列文章 1 关于数据仓库维度数据处理的方法探究系列—— 维的概述 2 关...

baoqiangwang
2018/06/26
0
0
11月30日区块链公开课Go语言探究比特币挖矿原理

今天扣丁学堂区块链培训直播公开课给大家介绍一下Go语言探究比特币挖矿原理,希望对同学们学习区块链开发有所帮助,下面我们一起来看一下。 腾讯课堂直播地址:https://ke.qq.com/course/32...

扣丁学堂
2018/11/30
0
0
java内存堆栈与引用之间的关联

内存堆栈的简单解释 a.为了对内存进行更加有效的管理,所以有了堆和栈. 堆内存地址可能是无序的,栈内存通常会有后进先出的规则(思考方法的执行原理). b.堆内存:使用new关键词获得的内存, c.栈...

leon_tan
2015/09/21
89
0
项目使用的Spring,使用jotm分布式事务管理,但是经常报内存溢出的错误,请大神看看

jdk使用的是1.6,tomcat用的是7.0,我感觉应该是配置文件的问题,现在我把配置文件贴出来,大神帮忙看一下,谢谢!!! 这里只贴出核心部分代码 每次报错都是一样的,警告信息也是一样的,序...

佐岸
2014/03/18
451
0
记一次 Bug 引发的 babel 升级

起因 最近参与了一个新的项目,是基于 React + Antd + Ts + Mobx 来写的。项目安装完依赖之后,启动的时候会看到控制台报错: 解决思路 当一个伸手党 google 搜索 探究原理,明白到底发生了什...

joking_zhang
09/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

ArrayList 源码分析

一、概述 本文基于 JDK8 ArrayList 底层通过动态数组的数据结构实现 内存需要连续的空间保证 添加操作涉及到数组的动态扩容 添加,删除都涉及到位置移动操作 随机查找效率快(下标查找) Ar...

hncboy
今天
4
0
采购单品汇总_华南.xlsx

import pandas as pdimport matplotlib.pyplot as pltimport matplotlib as mp1mp1.rcParams["font.family"] = "STFangsong"# 加载《销售》表数据df1 = pd.read_excel(r"C:\Us......

龙玉滕
今天
5
0
OSChina 周五乱弹 —— 一次四千 要4次还能多给一千

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @这次装个文艺青年吧 :#今日歌曲推荐# 分享金志文的单曲《远走高飞》: 版权又回来了现在听歌得好几个软件 《远走高飞》- 金志文 手机党少年们...

小小编辑
今天
11
0
Spring Cloud Alibaba 实战(十) - Spring Cloud GateWay

> 本文主要内容是:为什么要使用网关,整合Gateway,Gateway核心学习:Route,Predicate,Filter,最后使用Gateway聚合微服务请求 先总结至此的架构 1 网关的价值 不使用网关行嘛? 各个请求直接打在...

JavaEdge
今天
4
0
【CKB.DEV 茶话会】第二期:聊聊 CKB 钱包和 Nervos DAO 全流程

CKB.DEV 茶话会第二期:聊聊 CKB 钱包和 Nervos DAO 全流程 为了鼓励更多优秀的开发者和研究人员参与到 CKB 的开发和生态建设中去,我们希望组织一系列 CKB Developer Seminar(CKB.DEV 茶话...

NervosCommunity
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部