簡體   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