当前位置: 首页 > news >正文

郑州艾特软件 网站建设十大技能培训机构排名

郑州艾特软件 网站建设,十大技能培训机构排名,外贸网站建设如何做呢,推广网站建设花费得多少钱log4j日志配置文件中的%X{TransId}是怎么动态获取值的 在Log4j中,%X{TransId} 是用来从MDC(Mapped Diagnostic Context)中获取值的占位符。MDC 是 Log4j 提供的一种机制,用于在同一个线程的不同日志记录中传递上下文信息。通过 M…

log4j日志配置文件中的%X{TransId}是怎么动态获取值的

在Log4j中,%X{TransId} 是用来从MDC(Mapped Diagnostic Context)中获取值的占位符。MDC 是 Log4j 提供的一种机制,用于在同一个线程的不同日志记录中传递上下文信息。通过 MDC,你可以在日志中添加一些动态的上下文信息,比如事务ID、用户ID等。

要动态设置 TransId 的值,你需要在代码中使用 MDC.put 方法。以下是一个示例:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;public class Log4jExample {private static final Logger logger = LogManager.getLogger(Log4jExample.class);public static void main(String[] args) {// 设置TransId的值ThreadContext.put("TransId", "12345");// 记录日志logger.info("This is a log message with TransId.");// 清除TransId的值ThreadContext.clearMap();}
}

在上面的代码中,我们使用 ThreadContext.put("TransId", "12345") 来设置 TransId 的值。然后在日志配置文件中使用 %X{TransId} 占位符来引用这个值。

例如,log4j2.xml 配置文件可以这样配置:

<Configuration status="WARN"><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg %X{TransId}%n"/></Console></Appenders><Loggers><Root level="info"><AppenderRef ref="Console"/></Root></Loggers>
</Configuration>

在这个配置中,%X{TransId} 会被替换为 ThreadContextTransId 的值,即 12345

总结:通过在代码中使用 ThreadContext.put("TransId", "value") 方法设置 TransId 的值,然后在日志配置文件中使用 %X{TransId} 占位符来引用这个值,从而实现动态获取和记录 TransId

在Log4j 2中,ThreadContext 是用来替代 Log4j 1.x 中的 MDC 的。对于 Log4j 1.x,你需要使用 MDC.put 方法来设置上下文信息。以下是使用 Log4j 1.x 的示例:

import org.apache.log4j.Logger;
import org.apache.log4j.MDC;public class Log4jExample {private static final Logger logger = Logger.getLogger(Log4jExample.class);public static void main(String[] args) {// 设置TransId的值MDC.put("TransId", "12345");// 记录日志logger.info("This is a log message with TransId.");// 清除TransId的值MDC.clear();}
}

在上面的代码中,我们使用 MDC.put("TransId", "12345") 来设置 TransId 的值。然后在日志配置文件中使用 %X{TransId} 占位符来引用这个值。

例如,log4j.properties 配置文件可以这样配置:

log4j.rootLogger=INFO, Consolelog4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} - %m %X{TransId}%n

在这个配置中,%X{TransId} 会被替换为 MDCTransId 的值,即 12345

总结:对于 Log4j 1.x,通过在代码中使用 MDC.put("TransId", "value") 方法设置 TransId 的值,然后在日志配置文件中使用 %X{TransId} 占位符来引用这个值,从而实现动态获取和记录 TransId。对于 Log4j 2.x,使用 ThreadContext.put 方法来实现相同的功能。

ThreadLocal 是 Java 提供的一种机制,用于在每个线程中存储独立的变量副本。它可以确保变量在多线程环境下的线程安全性,而不需要显式的同步。每个线程都可以独立地修改自己的副本,而不会影响其他线程的副本。

ThreadLocal 的基本原理

  1. 独立副本:每个线程都有一个独立的变量副本,这些副本存储在 ThreadLocal 对象中。每个线程对其副本的修改不会影响其他线程的副本。

  2. 内部存储ThreadLocal 通过 Thread 类中的一个内部 ThreadLocalMap 来存储每个线程的变量副本。ThreadLocalMap 是一个自定义的哈希表,键是 ThreadLocal 对象,值是线程的变量副本。

  3. 访问机制:当线程访问 ThreadLocal 变量时,ThreadLocal 会根据当前线程获取对应的变量副本。如果当前线程没有对应的副本,ThreadLocal 会创建一个新的副本并存储在 ThreadLocalMap 中。

ThreadLocal 的主要方法

  • get():返回当前线程的变量副本。如果当前线程没有对应的副本,则调用 initialValue() 方法创建一个新的副本。
  • set(T value):设置当前线程的变量副本。
  • remove():移除当前线程的变量副本,防止内存泄漏。

示例代码

以下是一个简单的示例,展示了如何使用 ThreadLocal

public class ThreadLocalExample {// 创建一个ThreadLocal变量private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);public static void main(String[] args) {// 创建两个线程Thread thread1 = new Thread(() -> {for (int i = 0; i < 5; i++) {threadLocal.set(threadLocal.get() + 1);System.out.println(Thread.currentThread().getName() + " - " + threadLocal.get());}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 5; i++) {threadLocal.set(threadLocal.get() + 1);System.out.println(Thread.currentThread().getName() + " - " + threadLocal.get());}});thread1.start();thread2.start();}
}

在这个示例中,每个线程都有一个独立的 ThreadLocal 变量副本,互不干扰。

内部实现

ThreadLocal 的内部实现主要依赖于 ThreadLocalMap,这是一个自定义的哈希表,存储在每个线程的 Thread 对象中。以下是一些关键点:

  1. ThreadLocalMapThreadLocalMapThreadLocal 的静态内部类,用于存储每个线程的变量副本。它使用 ThreadLocal 对象作为键,变量副本作为值。

  2. EntryThreadLocalMap 中的每个条目是一个 Entry 对象,包含一个弱引用的 ThreadLocal 键和一个强引用的值。

  3. 垃圾回收:由于 ThreadLocal 键是弱引用,当 ThreadLocal 对象被垃圾回收时,ThreadLocalMap 中对应的条目会被自动清除,防止内存泄漏。

内存泄漏问题

使用 ThreadLocal 时需要注意内存泄漏问题。由于 ThreadLocalMap 中的键是弱引用,但值是强引用,如果不显式调用 remove() 方法,可能会导致内存泄漏。因此,建议在使用完 ThreadLocal 变量后,显式调用 remove() 方法清除变量副本。

threadLocal.remove();

总结ThreadLocal 提供了一种在多线程环境下存储和访问独立变量副本的机制,确保线程安全性。其内部通过 ThreadLocalMap 实现,每个线程都有一个独立的变量副本。使用时需要注意内存泄漏问题,建议在使用完后显式调用 remove() 方法清除变量副本。

ThreadLocalMapThreadLocal 类的一个静态内部类,用于存储每个线程的变量副本。它是 ThreadLocal 实现的核心部分。ThreadLocalMap 通过在每个线程的 Thread 对象中维护一个哈希表来实现这一功能。

ThreadLocalMap 的结构

ThreadLocalMap 是一个自定义的哈希表,包含以下几个关键部分:

  1. EntryThreadLocalMap 中的每个条目是一个 Entry 对象。EntryThreadLocalMap 的静态内部类,包含一个弱引用的 ThreadLocal 键和一个强引用的值。

    static class Entry extends WeakReference<ThreadLocal<?>> {/** The value associated with this ThreadLocal. */Object value;Entry(ThreadLocal<?> k, Object v) {super(k);value = v;}
    }
    
  2. TableThreadLocalMap 使用一个数组 table 来存储 Entry 对象。数组的大小是2的幂次方,以便于哈希冲突的处理。

    private Entry[] table;
    
  3. ThresholdThreadLocalMap 维护一个阈值 threshold,用于控制何时进行扩容。默认情况下,阈值是数组大小的2/3。

    private int threshold;
    

ThreadLocalMap 的主要方法

  1. set():将值存储到 ThreadLocalMap 中。如果键已经存在,则更新值;如果键不存在,则插入新的条目。

    private void set(ThreadLocal<?> key, Object value) {Entry[] tab = table;int len = tab.length;int i = key.threadLocalHashCode & (len - 1);for (Entry e = tab[i];e != null;e = tab[i = nextIndex(i, len)]) {ThreadLocal<?> k = e.get();if (k == key) {e.value = value;return;}if (k == null) {replaceStaleEntry(key, value, i);return;}}tab[i] = new Entry(key, value);int sz = ++size;if (!cleanSomeSlots(i, sz) && sz >= threshold)rehash();
    }
    
  2. get():从 ThreadLocalMap 中获取值。如果键存在,则返回对应的值;如果键不存在,则返回 null

    private Object getEntry(ThreadLocal<?> key) {int i = key.threadLocalHashCode & (table.length - 1);Entry e = table[i];if (e != null && e.get() == key)return e.value;elsereturn getEntryAfterMiss(key, i, e);
    }
    
  3. remove():从 ThreadLocalMap 中移除键值对。

    private void remove(ThreadLocal<?> key) {Entry[] tab = table;int len = tab.length;int i = key.threadLocalHashCode & (len - 1);for (Entry e = tab[i];e != null;e = tab[i = nextIndex(i, len)]) {if (e.get() == key) {e.clear();expungeStaleEntry(i);return;}}
    }
    

内存泄漏问题

由于 ThreadLocalMap 中的键是弱引用,当 ThreadLocal 对象被垃圾回收时,键会变成 null,但值仍然存在。这可能导致内存泄漏。因此,建议在使用完 ThreadLocal 变量后,显式调用 remove() 方法清除变量副本。

threadLocal.remove();

总结

  • ThreadLocalMapThreadLocal 的静态内部类,用于存储每个线程的变量副本。
  • EntryThreadLocalMap 的静态内部类,包含一个弱引用的 ThreadLocal 键和一个强引用的值。
  • ThreadLocalMap 使用一个数组 table 来存储 Entry 对象,并通过哈希算法和线性探测解决哈希冲突。
  • 主要方法 包括 set()get()remove(),用于存储、获取和移除键值对。
  • 内存泄漏问题:由于键是弱引用,值是强引用,建议在使用完 ThreadLocal 变量后显式调用 remove() 方法清除变量副本。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

http://www.ds6.com.cn/news/53014.html

相关文章:

  • 网站建设审核需要多长时间优化营商环境个人心得体会
  • 长春制作公司网站怎么进行推广
  • 做购物网站步骤百度官方优化指南
  • 网站如何做权重搜索引擎平台
  • 外贸网站建设报价国际新闻报道
  • 免费做初级会计试题网站有哪些海外市场推广方案
  • 国外做汽配的网站朋友圈广告推广文字
  • 浙江建设工程信息网站微信推广软件
  • 外汇局网站做结汇申报重庆森林壁纸
  • 网页设计网站测试宁波seo推荐推广平台
  • 建站都需要什么黄石seo
  • 网络运营岗位职责英文谷歌seo
  • 阳谷县住房建设委网站自助建站平台
  • 情女照片做杯子网站百度福州分公司
  • 校园招聘网站策划书网络推广公司联系方式
  • 怎么在服务器上面建设网站建站平台哪个比较权威
  • 网页设计与网站建设期末考试题安卓系统最好优化软件
  • 汕头在线制作网站免费b站推广网址有哪些
  • 英文建站多少钱营销网站建设教学
  • 网站不收录怎么办搜索引擎营销的方法不包括
  • wordpress 弹出搜索框合肥关键词优化平台
  • 专业网站建设渠道做一个公司网页多少钱
  • 医疗网站建设免费企业网站优化报告
  • 怎么学习网站建设百度如何收录网站
  • 佛山seo全网营销北京seo方法
  • 在门户网站中seo优化策略
  • 烟台网站建设方案托管做网站seo怎么赚钱
  • 快速做网站公司哪家专业哪个公司的网站制作
  • 什么网站可以做代购桂林seo
  • 通辽网站建设tlyltd吉林百度seo公司