ThreadLocal MDC
因为MDC底层是用ThreadLocal实现的,所以这里补充一些和ThreadLocal相关的知识点。
1.ThreadLocal的三个层次
关于ThreadLocal有三个层次,可以按照这三个层次去理解就不会乱。
三个层次
* 第一层是Thread空间,通过Thread.currentThread()获得。
* 第二层是Thread中的两个ThreadLocalMap,threadLocals和inheritableThreadLocals,访问thread对应的两个ThreadLocalMap成员变量获得。
* 第三层是每个ThreadLocalMap中key——ThreadLocal和value——ThreadLocal的set方法set的值,在get方法中用ThreadLocal的this作为ThreadLocalMap的key获取value。
* 无论什么操作都要按照这三个层次依次进行才不会乱
2.ThreadLocalMap
3.ThreadLocal的操作
- /**
- * Returns the value in the current thread's copy of this
- * thread-local variable. If the variable has no value for the
- * current thread, it is first initialized to the value returned
- * by an invocation of the {@link #initialValue} method.
- *
- * @return the current thread's value of this thread-local
- */
- public T get() {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null) {
- ThreadLocalMap.Entry e = map.getEntry(this);
- if (e != null)
- return (T)e.value;
- }
- return setInitialValue();
- }
- /**
- * Returns the value in the current thread's copy of this
- * thread-local variable. If the variable has no value for the
- * current thread, it is first initialized to the value returned
- * by an invocation of the {@link #initialValue} method.
- *
- * @return the current thread's value of this thread-local
- */
- public T get() {
- Thread t = Thread.currentThread();
- ThreadLocalMap map = getMap(t);
- if (map != null) {
- ThreadLocalMap.Entry e = map.getEntry(this);
- if (e != null)
- return (T)e.value;
- }
- return setInitialValue();
- }
4.InheritableThreadLocal
- /**
- * Get the map associated with a ThreadLocal.
- *
- * @param t the current thread
- */
- ThreadLocalMap getMap(Thread t) {
- return t.inheritableThreadLocals;
- }
- /**
- * Get the map associated with a ThreadLocal.
- *
- * @param t the current thread
- */
- ThreadLocalMap getMap(Thread t) {
- return t.inheritableThreadLocals;
- }
- /**
- * Create the map associated with a ThreadLocal.
- *
- * @param t the current thread
- * @param firstValue value for the initial entry of the table.
- * @param map the map to store.
- */
- void createMap(Thread t, T firstValue) {
- t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
- }
- /**
- * Create the map associated with a ThreadLocal.
- *
- * @param t the current thread
- * @param firstValue value for the initial entry of the table.
- * @param map the map to store.
- */
- void createMap(Thread t, T firstValue) {
- t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
- }
可以看出在初始化或者getMap的时候,获取到的都是inheritableThreadLocals引用,操作的也是inheritableThreadLocals这个ThreadLocalMap。
5.threadLocals和inheritableThreadLocals的初始化
- /**
- * Initializes a Thread.
- *
- * @param g the Thread group
- * @param target the object whose run() method gets called
- * @param name the name of the new Thread
- * @param stackSize the desired stack size for the new thread, or
- * zero to indicate that this parameter is to be ignored.
- */
- private void init(ThreadGroup g, Runnable target, String name,
- long stackSize) {
- ...
- Thread parent = currentThread();
- ...
- if (parent.inheritableThreadLocals != null)
- this.inheritableThreadLocals =
- ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
- ...
- }
- /**
- * Initializes a Thread.
- *
- * @param g the Thread group
- * @param target the object whose run() method gets called
- * @param name the name of the new Thread
- * @param stackSize the desired stack size for the new thread, or
- * zero to indicate that this parameter is to be ignored.
- */
- private void init(ThreadGroup g, Runnable target, String name,
- long stackSize) {
- ...
- Thread parent = currentThread();
- ...
- if (parent.inheritableThreadLocals != null)
- this.inheritableThreadLocals =
- ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
- ...
- }
在new一个Thread的时候会调用Thread的init方法,该方法中如果parent线程的inheritableThreadLocals不是null的话,就会用createInheritedMap方法,用parent的inheritableThreadLocals中的元素构造一个新的ThreadLocalMap。
6.parent线程
- Thread parent = currentThread();
- Thread parent = currentThread();
在Thread的init方法中,是通过获得当前线程作为parent线程,也就是说,在哪个线程中new的这个Thread并start的,执行该操作的线程就是new的新Thread的parent线程。
ThreadLocal MDC的更多相关文章
- 白话TCP/IP原理
TCP/IP(Transmission-Control-Protocol/Internet-Protocol),中文译名为传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议 ...
- slf4j MDC使用
slf4j MDC使用 最近也是在项目代码里发现一个地方有个MDC.put(),忍不住好奇点了进去,于是知道了MDC这个东西,细研究一下,发现还真是个好东西. MDC解决了什么问题 MDC全名Mapp ...
- Slf4j MDC 使用和 基于 Logback 的实现分析
前言 如今,在 Java 开发中,日志的打印输出是必不可少的, 关于 有了日志之后,我们就可以追踪各种线上问题.但是,在分布式系统中,各种无关日志穿行其中,导致我们可能无法直接定位整个操作流程.因此 ...
- logback MDC(Mapped Diagnostic Context)与分布式系统的跟踪系统
logback MDC(Mapped Diagnostic Context)与分布式系统的跟踪系统 logback官方文档中第8章Mapped Diagnostic Context给我们提供了一些分布 ...
- 多线程之美2一ThreadLocal源代码分析
目录结构 1.应用场景及作用 2.结构关系 2.1.三者关系类图 2.2.ThreadLocalMap结构图 2.3. 内存引用关系 2.4.存在内存泄漏原因 3.源码分析 3.1.重要代码片段 3. ...
- Hystrix实现ThreadLocal上下文的传递 转
springcloud微服务中, 服务间传输全局类参数,如session信息等. 一.问题背景 Hystrix有2个隔离策略:THREAD以及SEMAPHORE,当隔离策略为 THREAD 时,是没办 ...
- MDC 输出线程信息帮助定位问题
log4j中的%x ---NDC,%X---MDC 即%x NDC.clear();NDC.push(this.toString());%X{first} %X{last}MDC.put(" ...
- MDC是什么鬼?用法、源码一锅端
近期用到阿里的一款开源的数据同步工具 Canal,不经意之中看到了 MDC 的用法,而且平时项目中也多次用到 MDC,趁机科普一把. 通过今天的分享,能让你轻松 get 如下几点,绝对收获满满. a) ...
- ThreadLocal 是什么鬼?用法、源码一锅端
ThreadLocal 是一个老生常谈的问题,在源码学习以及实际项目研发中,往往都能见到它的踪影,用途比较广泛,所以有必要深入一番. 敢问,ThreadLocal 都用到了哪里?有没有运用它去解决过业 ...
随机推荐
- .condarc(conda 配置文件)、换国内源
原文地址 https://blog.csdn.net/lanchunhui/article/details/71379555 Configuration — Conda documentation . ...
- Jackcess 1.2.13 发布,Java 访问 Access 数据库
Jackcess 1.2.13 包含新的方法用于在数据库和附件内容解码中查找复杂值类型的关系,修复了 CodeHandler 相关的一些小 bug. Jackcess 是一个Java 类库,用来读写微 ...
- 日历控件My97DatePicker WdatePicker屏蔽 onchange的解决方法
http://www.cnblogs.com/wan-feng/archive/2013/12/13/3473439.html 受下面文章的启发,使用DatePicker自带的年月日相关的change ...
- linux中的通配符、元字符、转义符
linux中的通配符.元字符.转义符 linux中的通配符元字符转义符 shell命令的构成 通配符 元字符meta 转义符 example reference shell命令的构成 每条linux命 ...
- J2ee高并发情况下监听器
引言:在高并发下限制最大并发次数,在web.xml中用过滤器设置參数(最大并发数),并设置其它相关參数.具体见代码. 第一步:配置web.xml配置,不懂的地方解释一下:參数50通过參数名maxCon ...
- Verilog 加法器和减法器(3)
手工加法运算时候,我们都是从最低位的数字开始,逐位相加,直到最高位.如果第i位产生进位,就把该位作为第i+1位输入.同样的,在逻辑电路中,我们可以把一位全加器串联起来,实现多位加法,比如下面的四位加法 ...
- 奇怪吸引子---Chua
奇怪吸引子是混沌学的重要组成理论,用于演化过程的终极状态,具有如下特征:终极性.稳定性.吸引性.吸引子是一个数学概念,描写运动的收敛类型.它是指这样的一个集合,当时间趋于无穷大时,在任何一个有界集上出 ...
- quantum theory
the principles of quantum mechanics by p.a.m.dirac.
- require.js 最佳实践【转】
https://www.cnblogs.com/digdeep/p/4607131.html require.js是一个js库,相关的基础知识,前面转载了两篇博文:Javascript模块化编程(re ...
- 浅谈提升C#正则表达式效率
摘要:说到C#的Regex,谈到最多的应该就是RegexOptions.Compiled这个东西,传说中在匹配速度方面,RegexOptions.Compiled是可以提升匹配速度的,但在启动速度上 ...