编写一个示例程序,展示如何使用 ThreadLocal 类
以下是一个简单的示例程序,展示如何使用 ThreadLocal
来为每个线程维护独立的数据副本。
示例程序:使用 ThreadLocal 存储用户会话信息
public class ThreadLocalExample {
// 定义一个 ThreadLocal,用于存储每个线程的用户会话信息
private static ThreadLocal<String> userSession = ThreadLocal.withInitial(() -> "Guest");
public static void main(String[] args) {
// 模拟多个线程访问共享资源,但每个线程都有自己的独立数据
Thread thread1 = new Thread(() -> {
userSession.set("User1");
printSession();
});
Thread thread2 = new Thread(() -> {
userSession.set("User2");
printSession();
});
Thread thread3 = new Thread(() -> {
// 使用默认值(Guest)
printSession();
});
thread1.start();
thread2.start();
thread3.start();
}
// 打印当前线程的用户会话信息
private static void printSession() {
System.out.println(Thread.currentThread().getName() + " session: " + userSession.get());
// 清理线程本地变量,避免潜在内存泄漏
userSession.remove();
}
}
程序输出(可能因线程调度顺序不同而变化):
Thread-0 session: User1
Thread-1 session: User2
Thread-2 session: Guest
程序说明:
ThreadLocal
的创建:- 通过
ThreadLocal.withInitial()
方法创建,设置默认值为"Guest"
。
- 通过
- 独立数据存储:
- 每个线程通过调用
userSession.set()
存储自己的数据。 - 即使多个线程访问同一个
ThreadLocal
实例,它们的数据是隔离的。
- 每个线程通过调用
- 数据访问与清理:
- 使用
userSession.get()
获取当前线程的值。 - 使用
userSession.remove()
在任务结束后清理数据,防止潜在的内存泄漏。
- 使用
扩展:更复杂的场景(模拟数据库连接管理)
public class DatabaseConnectionManager {
// ThreadLocal 模拟每个线程独立的数据库连接
private static ThreadLocal<String> connection = ThreadLocal.withInitial(() -> "DefaultConnection");
public static void main(String[] args) {
// 模拟两个线程
Thread thread1 = new Thread(() -> {
connection.set("DBConnection1");
useDatabase();
});
Thread thread2 = new Thread(() -> {
connection.set("DBConnection2");
useDatabase();
});
thread1.start();
thread2.start();
}
private static void useDatabase() {
System.out.println(Thread.currentThread().getName() + " using " + connection.get());
// 清理连接
connection.remove();
}
}
输出:
Thread-0 using DBConnection1
Thread-1 using DBConnection2