编写一个示例程序,展示如何使用 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

程序说明:

  1. ThreadLocal 的创建
    • 通过 ThreadLocal.withInitial() 方法创建,设置默认值为 "Guest"
  2. 独立数据存储
    • 每个线程通过调用 userSession.set() 存储自己的数据。
    • 即使多个线程访问同一个 ThreadLocal 实例,它们的数据是隔离的。
  3. 数据访问与清理
    • 使用 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

发表评论

后才能评论