ThreadLocal 和 InheritableThreadLocal 都是 Java 中用于实现线程私有变量的类,它们的原理和用途略有不同。
-
ThreadLocal 的原理:
-
每个线程都有一个独立的 ThreadLocal 实例,用于存储线程私有的变量副本。
-
当通过 ThreadLocal 的 get() 方法获取变量值时,实际上是通过当前线程对象作为 key,在 ThreadLocalMap 中查找对应的 value(变量副本)。
-
每个 ThreadLocal 实例内部都有一个 ThreadLocalMap 对象,用于存储线程与变量副本之间的映射关系。
-
当第一次调用 ThreadLocal 的 get() 方法时,如果当前线程没有与之对应的变量副本,ThreadLocal 会调用 initialValue() 方法创建一个初始值作为变量副本,并将其存储在 ThreadLocalMap 中。
-
后续调用 get() 方法时,直接从 ThreadLocalMap 中获取变量副本。
-
在线程执行完毕后,ThreadLocalMap 会随着线程的销毁而销毁,从而清除线程相关的变量副本。
-
-
InheritableThreadLocal 的原理:
-
InheritableThreadLocal 是 ThreadLocal 的一个子类,它的作用是在父线程和子线程之间共享变量副本。
-
InheritableThreadLocal 使用了线程继承的机制,即子线程可以从父线程继承父线程的 InheritableThreadLocal 变量的副本。
-
在父线程中创建的 InheritableThreadLocal 变量的副本会被传递给子线程,子线程可以通过 InheritableThreadLocal 的 get() 方法获取父线程设置的变量副本。
-
类似 ThreadLocal,每个线程都有一个 InheritableThreadLocalMap 对象,用于存储线程与变量副本之间的映射关系。
-
当子线程创建时,会从父线程的 InheritableThreadLocalMap 中复制变量副本,并将其存储在子线程的 InheritableThreadLocalMap 中,以实现变量的共享。
-
需要注意的是,InheritableThreadLocal 并不适用于所有场景,它的使用可能会导致线程间的耦合性增加,且在高并发环境下需要注意对共享变量的并发访问问题。在选择使用 ThreadLocal 或 InheritableThreadLocal 时,需要根据具体的业务场景和线程之间的关系来进行权衡和选择。