java

What happens when different ThreadLocals refer to the same object?


If I have (napkin) code that looks like this:

public static SomeClass someInstance;
ThreadLocal<HashMap<Integer, SomeClass>> locals = new ThreadLocal<>(){
    @Override protected HashMap<Integer, SomeClass> initialValue() {
        return new HashMap<Integer,SomeClass>(){{put(5,someInstance);}};
    }

}

What does it actually do? If thread1 mutates someClass by accessing it through its threadlocal hashmap, will those changes be visible to thread2 (eventually)?

It's fine for my use if there's a race condition between when the data is written to someClass and when another thread observes the change, but it won't be fine if the reader thread will never see the change even after a long time has passed.


Solution

  • Your concern is not specifically related to using ThreadLocal; the problems you envision will also occur if you share a mutable object with multiple threads through other means, and modify that object.

    For changes to be guaranteed to be visible (eventually or not), you need to implement SomeClass to be properly thread safe, otherwise there is no guarantee that those changes will be seen or not by other threads. And to be thread safe, as defined in the Java Memory Model (JMM), you need to use synchronization primitives, locks and other publication mechanisms that establish a happens-before between the write by one thread and the subsequent read by another thread (and also with writes performed by other threads).