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不受线程安全保护?我知道“字符串”始终是线程安全的。
答案 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