ThreadLocal的目的是什么?

时间:2019-11-25 21:55:40

标签: java concurrency thread-local

public class VPattern implements Pattern
{
    private final TokenKey tokenKey_;
    private final String tokenLabel_;
    private Integer cachedHashCode_ = null;
    private ThreadLocal<Token> token_ = new ThreadLocal<Token>();

    ...
}

我正在阅读这段代码,并且在这里不了解ThreadLocal的用法。那是因为ThreadLocal用于确保'token_'对象在任何并发情况下都是线程安全的吗?如果是这样,为什么TokenKey和Integer不受线程安全保护?我知道“字符串”始终是线程安全的。

2 个答案:

答案 0 :(得分:2)

每个线程都拥有自己的Token,即使它们共享相同的VPattern实例。之所以可能这样做是因为Token不是线程安全的,并且VPattern要避免同步对Token实例的访问。 tokenKey_是最终版本,因此不必担心字段更改,也许它本身就是线程安全的。 tokenLabel_也是最终的,字符串是不可变的,因此没有问题。 cachedHashCode_是这里的奇数;对它的访问受到某种保护吗?不看剩下的课就很难说发生了什么。

答案 1 :(得分:1)

通常,ThreadLocal可以为每个工作线程提供不同的对象。因此,如果给定的对象不是线程安全的也不是单例的,则可以将其存储在ThreadLocal变量中。然后,每个线程都可以安全地使用类的不同实例。您可以将其视为地图,其中当前线程是键,而实际对象是值。

我们假设有两个线程同时工作并共享一个VPattern对象。如果线程获得tokenKey_tokenLabel_,则两个线程将获得相同的实例。但是,如果两个线程都调用token.get(),则它们将获得Token类型的不同实例(如果先前已初始化,请参见:set方法和withInitial静态工厂方法)。

不幸的是,很难说ThreadLocal的目的是什么,因为它高度依赖于上下文。似乎Token对象不能由不同的线程共享(每个线程应具有自己的令牌)。

您可以在Javadoc或此处阅读有关ThreadLocal的更多信息:https://www.baeldung.com/java-threadlocal