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时,就会将parentinheritableThreadLocals,赋值给前线程的inheritableThreadLocals。说白了,就是如果当前线程的inheritableThreadLocals不为null,就从父线程哪里拷贝过来一个过来,类似于另外一个ThreadLocal,但是数据从父线程那里来的

 

8. ThreadLocal的应用场景和使用注意点

ThreadLocal的很重要一个注意点,就是使用完,要手动调用remove()

ThreadLocal的应用场景主要有以下这几种:

  • 使用日期工具类,当用到SimpleDateFormat,使用ThreadLocal保证线性安全
  • 全局存储用户信息(用户信息存入ThreadLocal,那么当前线程在任何地方需要时,都可以使用)
  • 保证同一个线程,获取的数据库连接Connection是同一个,使用ThreadLocal来解决线程安全的问题
  • 使用MDC保存日志信息。

 

转自:https://blog.csdn.net/gongzi_9/article/details/126754648

posted on 2024-08-21 10:09  lshan  阅读(19)  评论(0编辑  收藏  举报