简体   繁体   中英

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. 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:

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. 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.


See section 12.4.2 of JLS that describes this very thing in detail.

EDIT : And what you are trying is perfectly fine. From the javadocs of ThreadLocal:

ThreadLocal instances are typically private static fields in classes that wish to associate state with a thread (eg, a user ID or Transaction 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. You can easily provide a thread specific initial value by overriding the initialValue() method. One way to do that is with an anonymous inner class 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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