ThreadLocal的常用分类
new TransmittableThreadLocal<>()
是 TransmittableThreadLocal 类的实例化,它是一个扩展了 ThreadLocal
的类,用于在跨线程传递数据时的线程局部变量。它与常规的 ThreadLocal
类似,但有一个重要的不同之处,就是它能够在线程间传递数据,这对于线程池和异步执行等场景非常有用。
1. TransmittableThreadLocal
与 ThreadLocal
的区别
-
ThreadLocal:每个线程都有自己独立的局部变量副本,不同线程之间的副本是隔离的。因此,在传统的
ThreadLocal
中,线程之间的局部变量是不可传递的。 -
TransmittableThreadLocal:它是
ThreadLocal
的一个扩展,支持在多线程环境中跨线程传递数据。这个特性在使用线程池或异步任务执行时尤其有用,因为这些任务可能会跨线程切换,需要保留或传递原线程的局部变量。
例如,TransmittableThreadLocal
能确保即使线程池中的任务由不同线程执行,它仍然能够将主线程中的局部变量传递到新的线程中。
示例:TransmittableThreadLocal
import com.alibaba.ttl.TransmittableThreadLocal;
public class TransmittableThreadLocalExample {
private static TransmittableThreadLocal<String> transmittableThreadLocal = new TransmittableThreadLocal<>();
public static void main(String[] args) {
// 设置主线程中的局部变量
transmittableThreadLocal.set("Main thread value");
// 创建并启动子线程
Thread thread = new Thread(() -> {
// 这个值会被从主线程传递到当前线程
System.out.println("In child thread: " + transmittableThreadLocal.get());
});
thread.start();
}
}
在这个例子中,TransmittableThreadLocal
在主线程中设置了一个值,并确保子线程能够访问到主线程中的这个值,这在传统的 ThreadLocal
中是不可能的。
2. ThreadLocal
的分类
ThreadLocal
在 Java 中可以从不同的角度进行分类。主要有以下几种分类方式:
按 功能 分类:
-
常规的 ThreadLocal:
- 这是标准的
ThreadLocal
类,适用于每个线程都有独立副本的场景。每个线程都会有自己的局部变量副本,这些副本在其他线程中不可见。 - 适用于线程间没有共享数据,或者每个线程需要独立的状态。
- 这是标准的
-
TransmittableThreadLocal(传递型线程局部变量):
- 这是
ThreadLocal
的扩展,支持在线程之间传递局部变量,特别适用于线程池和异步执行的场景。 - 适用于在跨线程的情况下需要共享或传递局部数据的场景,例如在使用线程池时,需要将一个线程的局部变量传递给另一个线程。
- 这是
-
InheritableThreadLocal(可继承线程局部变量):
- 与
ThreadLocal
类似,但是其值会被子线程继承。当父线程设置了局部变量时,子线程能够获取到该值。 - 适用于子线程需要继承父线程的状态信息的场景。
示例:
public class InheritableThreadLocalExample { private static InheritableThreadLocal<String> inheritableThreadLocal = new InheritableThreadLocal<>(); public static void main(String[] args) { inheritableThreadLocal.set("Parent thread value"); Thread childThread = new Thread(() -> { // 子线程可以继承父线程的值 System.out.println("Child thread inherited value: " + inheritableThreadLocal.get()); }); childThread.start(); } }
在这个例子中,子线程继承了父线程的局部变量
inheritableThreadLocal
的值。 - 与
按 生命周期 分类:
-
线程绑定的局部变量:
- 每个线程都有自己独立的副本,线程结束后,副本就会被销毁。适用于线程独立的状态。
-
跨线程传递的局部变量:
- 通过
TransmittableThreadLocal
可以让一个线程中的局部变量在跨线程时被传递,适用于线程池、异步任务等场景。
- 通过
3. 何时使用 ThreadLocal
、InheritableThreadLocal
和 TransmittableThreadLocal
?
- 使用
ThreadLocal
:当每个线程需要有独立的状态时。例如数据库连接池中的连接对象,每个线程处理自己的数据库连接。 - 使用
InheritableThreadLocal
:当子线程需要继承父线程的某些状态信息时。例如,当需要将主线程的一些信息(如用户信息)传递给子线程时,可以使用InheritableThreadLocal
。 - 使用
TransmittableThreadLocal
:当跨线程传递线程局部变量时,特别是在异步任务或者线程池场景下,需要确保主线程中的局部变量能够传递到线程池的工作线程中时。
4. 总结
ThreadLocal
是一种线程局部存储,主要用于每个线程保存独立的变量副本,避免线程间共享数据。TransmittableThreadLocal
是ThreadLocal
的扩展,支持跨线程传递数据,适用于线程池和异步任务的场景。InheritableThreadLocal
是支持父子线程传递数据的ThreadLocal
扩展,子线程能够继承父线程的局部变量。