简体   繁体   English

Java中的ThreadLocal初始化?

[英]ThreadLocal Initialization in Java?

I'm building a singleton that has a ThreadLocal as an instance variable, this singleton has a method that may be accessed by multiple threads and it is lazily instantiated. 我正在构建一个具有ThreadLocal作为实例变量的单例,此单例具有可由多个线程访问的方法,并且它是延迟实例化的。 Right now I'm thinking on something like this: 现在,我正在考虑这样的事情:

static final ThreadLocal<HashMap> bindingContext = new ThreadLocal<HashMap>();

But I'm not sure if it is a good idea, I also have the option to make it an instance variable since I'm using it (as I said on a singleton). 但是我不确定这是否是一个好主意,因为我正在使用它,所以我也可以选择使其成为实例变量(正如我在单例中所说)。

So the question is, where is the best place to initialize that class variable or should it be a class variable at all? 所以问题是,初始化该类变量的最佳位置在哪里,或者根本不应该是一个类变量?

It is guaranteed that static initializers are executed in a thread safe way. 确保以线程安全的方式执行静态初始化器。 The JLS specifically mentions this: JLS特别提到了这一点:

Because the Java programming language is multithreaded, initialization of a class or interface requires careful synchronization, since some other thread may be trying to initialize the same class or interface at the same time. 因为Java编程语言是多线程的,所以类或接口的初始化需要仔细的同步,因为某些其他线程可能试图同时初始化同一类或接口。 There is also the possibility that initialization of a class or interface may be requested recursively as part of the initialization of that class or interface; 还可能会递归地请求类或接口的初始化,作为该类或接口的初始化的一部分; for example, a variable initializer in class A might invoke a method of an unrelated class B, which might in turn invoke a method of class A. The implementation of the Java virtual machine is responsible for taking care of synchronization and recursive initialization by using the following procedure. 例如,类A中的变量初始值设定项可能会调用不相关的类B的方法,而后者又可能会调用类A 方法。Java虚拟机的实现负责通过使用同步来实现同步和递归初始化 。遵循以下步骤。


See section 12.4.2 of JLS that describes this very thing in detail. 请参阅JLS的12.4.2其中详细介绍了此内容。

EDIT : And what you are trying is perfectly fine. 编辑 :并且您正在尝试的完全没问题。 From the javadocs of ThreadLocal: 从ThreadLocal的javadocs中:

ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (eg, a user ID or Transaction ID). ThreadLocal实例通常是希望将状态与线程关联的类中的私有静态字段(例如,用户ID或事务ID)。

The static member will insure that a new ThreadLocal will be created, but the initial value of that ThreadLocal will be null for each new thread. 静态成员将确保将创建一个新的ThreadLocal,但是对于每个新线程,该ThreadLocal的初始值将为null。 You can easily provide a thread specific initial value by overriding the initialValue() method. 您可以通过覆盖initialValue()方法来轻松提供特定于线程的初始值。 One way to do that is with an anonymous inner class EG 一种方法是使用匿名内部类EG

static final ThreadLocal<HashMap> bindingContext = new ThreadLocal<HashMap>() {
    @Override protected HashMap initialValue() {return new HashMap();}
    };

使用Lamda时,我们可以这样写:

private ThreadLocal<Map<String,String>> bindingContext = ThreadLocal.withInitial(HashMap::new);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM