1

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?

3 Answers3

4

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 (e.g., a user ID or Transaction ID).

Suraj Chandran
  • 24,433
  • 12
  • 63
  • 94
  • @tom No. There is no Exception. At the level of JLS, there is no ThreadLocal or anything. Its generic – Suraj Chandran Jun 12 '12 at 18:48
  • +1 For the explanation, but it does not answer my question :) – Juan Alberto López Cavallotti Jun 12 '12 at 18:52
  • if I understand the question correctly, it cannot be guaranteed that his singleton will return the correct object in a multi-thread environment since `ThreadLocal` is linked to the current thread. His singleton will return the object in the current thread. I believe the singleton pattern in combination with `ThreadLocal` is a bad choice in this case. – tom Jun 12 '12 at 18:52
  • @JuanAlbertoLópezCavallotti What part is not answered.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 (e.g., a user ID or Transaction ID)." – Suraj Chandran Jun 12 '12 at 18:59
  • @tom according to javadocs this itself is the recommended way of using a thread local. See my edited answer – Suraj Chandran Jun 12 '12 at 18:59
  • Well, I must have understood the question wrong. I thought he tried to share a state application wide. No offense intended. – tom Jun 12 '12 at 19:05
  • does it have to be static if my instance I get is going to be singleton? – brain storm Jan 18 '19 at 00:21
1

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

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

with Lamda usage, we can write this way:

private ThreadLocal<Map<String,String>> bindingContext = ThreadLocal.withInitial(HashMap::new);
Patrick W
  • 1,485
  • 4
  • 19
  • 27
GLM
  • 59
  • 2