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