简体   繁体   English

ThreadLocal 线程安全吗?

[英]Is ThreadLocal thread safe?

For example, we have a static ThreadLocal field an a setter:例如,我们有一个 static ThreadLocal 字段和一个 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?我想知道,由于java.lang.ThreadLocal#set方法中没有隐式同步,这里线程安全的保证是什么? 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.我知道 TreadLocal class 本质上是完全线程安全的,但我不明白它是如何实现的。

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);
}

It's safe because getMap returns the map for the given (ie current) thread. 这是安全的,因为getMap返回给定(即当前)线程的映射。 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. 所以,它是真正下到实施getMap以确保是正常的任何话题-而据我所看到的,只是委托给内场Thread对象。 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 :) 这不是很清楚,我是否getMap中的任何线程曾通过其他比当前线程-如果是这样,这可能是潜在的麻烦-但我怀疑这一切都经过精心编写的,以确保这不是一个问题:)

Adding on to Jon's answer, I agree, the map is the sole property of the current thread.除了 Jon 的回答,我同意 map 是当前线程的唯一属性。

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, ie common to all threads) for getting hash index into the table.而这个 ThreadLocalMap 存储了一个表,里面只引用了调用 ThreadLocal object(它位于 Heap 空间,即所有线程共有),用于获取表中的 hash 索引。 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.因此,如果您的 ThreadLocal object 在多个线程之间共享,并且每个线程同时调用 get 或 set,它们实际上是在自己的 ThreadLocalMap 中包含的表副本中设置值,该表存储在 Thread class 中作为非static 字段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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