iozee
iozee

Reputation: 1349

Is ThreadLocal thread safe?

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

Answers (2)

Amit
Amit

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

Jon Skeet
Jon Skeet

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

Related Questions