Reputation: 1349
For example, we have a static ThreadLocal field an a setter:
private static final ThreadLocal threadLocalField = new ThreadLocal;
public static void getSXTransaction() {
threadLocalField.set(new MyValue());
}
I wonder, what are the guarantees of thread safety here as there is no implicit synchronization in the java.lang.ThreadLocal#set method? I know it makes sense for the TreadLocal class to be fully thread safe by it's nature but I cannot understand how it's being accomplished.
Here is the source code for it:
/**
* Sets the current thread's copy of this thread-local variable
* to the specified value. Most subclasses will have no need to
* override this method, relying solely on the {@link #initialValue}
* method to set the values of thread-locals.
*
* @param value the value to be stored in the current thread's copy of
* this thread-local.
*/
public void set(T value) {
Thread t = Thread.currentThread();
ThreadLocalMap map = getMap(t);
if (map != null)
map.set(this, value);
else
createMap(t, value);
}
Upvotes: 10
Views: 8756
Reputation: 101
Adding on to Jon's answer, I agree, the map is the sole property of the current thread.
ThreadLocalMap getMap(Thread t) {
return t.threadLocals;
}
And this ThreadLocalMap stores a table inside which only refers to the calling ThreadLocal object (which sits in the Heap space, i.e. common to all threads) for getting hash index into the table. But the actual value is stored inside this table which is per thread.
So if your ThreadLocal object is shared between multiple threads and each thread call get or set at the same time on it, they're literally setting the values in their own copies of the table contained inside ThreadLocalMap which is stored inside Thread class as a non static field.
Upvotes: 0
Reputation: 1500525
It's safe because getMap
returns the map for the given (i.e. current) thread. No other thread is going to be messing with that. So it's really down to the implementation of getMap
to make sure that's is okay for any thread - and as far as I can see, that just delegates to a field within the Thread
object. It's not clear to me whether getMap
is ever passing in any thread other than the current thread - if it were, that could be potentially tricky - but I suspect it's all been written carefully to make sure that's not a problem :)
Upvotes: 21