线程-ThreadLocal
ThreadLocal
是 Java 中的一个类,提供了一种创建线程局部变量的机制。每个访问 ThreadLocal
变量的线程都有一个独立的、初始化的变量副本。
这可以避免线程间的同步问题,因为每个线程只能访问自己的ThreadLocal变量。通过ThreadLocal为线程添加的值只能由这个线程访问到,其他的线程无法访问,因此就避免了多线程之间的同步问题。
常用方法
T get()
:返回当前线程所持有的线程局部变量的副本。void set(T value)
:为当前线程设置线程局部变量的值。void remove()
:移除当前线程所持有的线程局部变量,释放该变量的内存。protected T initialValue()
:返回线程局部变量的初始值(可以被子类重写)。
初始化:创建ThreadLocal变量。
private static ThreadLocal<T> threadLocal = new ThreadLocal<>();
设置值:使用set(T value)方法为当前线程设置值。
threadLocal.set(value);
获取值:使用get()方法获取当前线程的值。
T value = threadLocal.get();
移除值:使用remove()方法在线程结束时清除ThreadLocal变量,以避免内存泄漏。
threadLocal.remove();
使用一
public class ThreadLocalExample {
// 创建一个 ThreadLocal 变量 并用 withInitial 方法指定了初始值为 1。
private static ThreadLocal<Integer> threadLocalValue = ThreadLocal.withInitial(() -> 1);
public static void main(String[] args) {
Runnable task = () -> {
// 获取当前线程的线程局部变量的值
Integer value = threadLocalValue.get();
System.out.println("Initial Value in " + Thread.currentThread().getName() + ": " + value);
// 设置当前线程的线程局部变量的值
threadLocalValue.set(value + 1);
System.out.println("Updated Value in " + Thread.currentThread().getName() + ": " + threadLocalValue.get());
};
// 创建多个线程来演示
Thread thread1 = new Thread(task, "Thread-1");
Thread thread2 = new Thread(task, "Thread-2");
thread1.start();
thread2.start();
}
}
//输出
Initial Value in Thread-1: 1
Initial Value in Thread-2: 1
Updated Value in Thread-1: 2
Updated Value in Thread-2: 2
使用二
定义ThreadLocal工具类
public class LoginUserContext {
//定义SystemUser工具类,在同一个线程内就不需要再重复获取数据库的SystemUser了,直接在ThreadLocal中拿
private static final ThreadLocal<SystemUser> userThreadLocal = new ThreadLocal<>();
//设置值
public static void setLoginUser(SystemUser systemUser) {
userThreadLocal.set(systemUser);
}
//获取值
public static SystemUser getLoginUser() {
return userThreadLocal.get();
}
//清除userThreadLocal
public static void clear() {
userThreadLocal.remove();
}
}
注意事项
- 内存泄漏:如果
ThreadLocal
变量不再使用,但有线程一直在使用,可能会导致内存泄漏。应当在不需要时调用remove()
方法。 - 使用场景:适用于需要保持线程独立状态的场景,比如用户会话、数据库连接、或是一些缓存数据等。