繁体   English   中英

ThreadLocal 线程安全吗?

[英]Is ThreadLocal thread safe?

例如,我们有一个 static ThreadLocal 字段和一个 setter:

private static final ThreadLocal threadLocalField = new ThreadLocal;

public static void getSXTransaction() {
  threadLocalField.set(new MyValue());
}

我想知道,由于java.lang.ThreadLocal#set方法中没有隐式同步,这里线程安全的保证是什么? 我知道 TreadLocal class 本质上是完全线程安全的,但我不明白它是如何实现的。

这是它的源代码:

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

这是安全的,因为getMap返回给定(即当前)线程的映射。 没有其他线程可以搞乱这一点。 所以,它是真正下到实施getMap以确保是正常的任何话题-而据我所看到的,只是委托给内场Thread对象。 这不是很清楚,我是否getMap中的任何线程曾通过其他比当前线程-如果是这样,这可能是潜在的麻烦-但我怀疑这一切都经过精心编写的,以确保这不是一个问题:)

除了 Jon 的回答,我同意 map 是当前线程的唯一属性。

ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

而这个 ThreadLocalMap 存储了一个表,里面只引用了调用 ThreadLocal object(它位于 Heap 空间,即所有线程共有),用于获取表中的 hash 索引。 但是实际值存储在每个线程的这个表中。

因此,如果您的 ThreadLocal object 在多个线程之间共享,并且每个线程同时调用 get 或 set,它们实际上是在自己的 ThreadLocalMap 中包含的表副本中设置值,该表存储在 Thread class 中作为非static 字段。

暂无
暂无

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

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