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 都用到了哪里?有没有运用它去解决过业 ...
随机推荐
- Linux 批量查找替换方法(VIM和sed)
版权声明:欢迎与我交流讨论,若要转载请注明出处~ https://blog.csdn.net/sinat_36053757/article/details/70946263 1.VIM命令 当前行进行 ...
- vim去除行显示;vim全部复制命令
行显示和隐藏: set nu set nu! 直接上命令: ggVG*y 解释一下上面的命令: ggVG ——全选 *y —— 复制到剪贴板 gg 是光标定位到文件首行 V 是进入可视模式 G ...
- Guava Finalizer
/* * Copyright (C) 2008 The Guava Authors Licensed under the Apache License, Version 2.0 (the " ...
- jquery each循环遍历完再执行的方法 因为each是异步的 所以要加计数器.
query each循环遍历完再执行的方法因为each是异步的 所以要加计数器.var eachcount=0;$(“.emptytip”).each(function(){ eachcount++c ...
- SQL Server跨服务器查询的实现方法,OpenDataSource
SQL Server跨服务器查询的方法我们经常需要用到,下面就为您介绍两种SQL Server跨服务器查询的方法,如果您感兴趣的话,不妨一看. SQL Server跨服务器查询方法一:用OPENDAT ...
- 【UOJ Round #5】
构造+贪心/数论 为什么只有两个标题呢……因为第二题我不会…… 怎样提高智商 构造题……然而一开始半天我都yy不出来…… 后来我想:这题应该不会特别麻烦,而且既然样例只给了1,可能再给大一点就让人发现 ...
- 使用mmap可以方便地添加共享内存
使用mmap添加的共享内存. 局限: 只能在有亲属关系的进程之间使用. #include <stdio.h> #include <stdlib.h> #include < ...
- JavaScript中textRange对象使用方法总结
TextRange对象是动态HTML(DHTML)的高级特性,使用它可以实现很多和文本有关的任务,例如搜索和选择文本.文本范围让您可以选择性的将字符.单词和句子从文档中挑选出来.TextRange对象 ...
- Java-JUC(十):线程按序交替执行
问题: 有a.b.c三个线程,使得它们按照abc依次执行10次. 实现: package com.dx.juc.test; import java.util.concurrent.locks.Cond ...
- Java-JUC(二):Java内存模型可见性、原子性、有序性及volatile具有特性
1.Java HotSpot JVM运行时数据区 Java内存模型即Java Memory Model,简称JMM.JMM定义了Java 虚拟机(JVM)在计算机内存(RAM)中的工作方式.JVM是整 ...