https://www.baeldung.com/java-threadlocal

1. 概述

在本教程中,我们将研究java.lang包中的 ThreadLocal构造。这使我们能够单独存储当前线程的数据并将其简单地包装在特殊类型的对象中。

2. ThreadLocal API

TheadLocal构造允许我们存储只能由特定线程访问的数据。

假设我们想要一个与特定线程捆绑在一起的整数值:

ThreadLocal<Integer> threadLocalValue = new ThreadLocal<>();

接下来,当我们想从线程中使用这个值时,我们只需要调用get()或set()方法。简单地说,我们可以想象ThreadLocal将数据存储在一个以线程为键的映射中。

因此,当我们在threadLocalValue上调用get()方法时,我们将获得请求线程的整数值:

threadLocalValue.set(1);
Integer result = threadLocalValue.get();

我们可以使用withInitial()静态方法并将供应商传递给它来构造ThreadLocal的实例:

ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 1);

要从ThreadLocal中删除值,我们可以调用 *remove()*方法:

threadLocal.remove();

为了了解如何正确使用ThreadLocal,我们首先看一个不使用ThreadLocal的示例,然后我们将重写我们的示例以利用该构造。

3. 将用户数据存储在 Map 中

让我们考虑一个需要根据给定的用户 ID存储用户特定的上下文数据的程序:

public class Context {
    private String userName;

    public Context(String userName) {
        this.userName = userName;
    }
}

我们希望每个用户 ID 都有一个线程。我们将创建一个实现Runnable接口的**SharedMapWithUserContext类。run ()方法中的实现通过UserRepository类调用某个数据库,该类返回给定userId的**Context对象。