ThreadLocalUtil.java
public class ThreadLocalUtil { static final ThreadLocal THREAD_LOCAL = new ThreadLocal(); public static <T> T get() { return (T) THREAD_LOCAL.get(); } public static void set(Object value) { THREAD_LOCAL.set(value); } public static void remove() { THREAD_LOCAL.remove(); } }
7. InheritableThreadLocal保证父子线程间的共享数据
我们知道ThreadLocal是线程隔离的,如果我们希望父子线程共享数据,如何做到呢?可以使用InheritableThreadLocal。先来看看demo:
public class InheritableThreadLocalTest { public static void main(String[] args) { ThreadLocal<String> threadLocal = new ThreadLocal<>(); InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>(); threadLocal.set("你好,七度"); inheritableThreadLocal.set("你好,七度"); Thread thread = new Thread(()->{ System.out.println("ThreadLocal value " + threadLocal.get()); System.out.println("InheritableThreadLocal value " + inheritableThreadLocal.get()); }); thread.start(); } } // 运行结果 ThreadLocal value null InheritableThreadLocal value 你好,七度
可以发现,在子线程中,是可以获取到父线程的 InheritableThreadLocal 类型变量的值,但是不能获取到 ThreadLocal 类型变量的值。
获取不到ThreadLocal 类型的值,我们可以好理解,因为它是线程隔离的嘛。InheritableThreadLocal 是如何做到的呢?原理是什么呢?
在Thread类中,除了成员变量threadLocals之外,还有另一个成员变量:inheritableThreadLocals。它们两类型是一样的:
当parent的inheritableThreadLocals不为null时,就会将parent的inheritableThreadLocals,赋值给前线程的inheritableThreadLocals。说白了,就是如果当前线程的inheritableThreadLocals不为null,就从父线程哪里拷贝过来一个过来,类似于另外一个ThreadLocal,但是数据从父线程那里来的
8. ThreadLocal的应用场景和使用注意点
ThreadLocal的很重要一个注意点,就是使用完,要手动调用remove()。
而ThreadLocal的应用场景主要有以下这几种:
- 使用日期工具类,当用到
SimpleDateFormat,使用ThreadLocal保证线性安全 - 全局存储用户信息(用户信息存入
ThreadLocal,那么当前线程在任何地方需要时,都可以使用) - 保证同一个线程,获取的数据库连接
Connection是同一个,使用ThreadLocal来解决线程安全的问题 - 使用
MDC保存日志信息。
转自:https://blog.csdn.net/gongzi_9/article/details/126754648
浙公网安备 33010602011771号