2013-08-29 63 views
4

如果我使用threadlocal變量,那麼每個線程都會獲取變量的本地副本。我的第一個問題是,如果每個線程變異變量,變異的值是否會保留在其本地副本中?或者在某些時候它會嘗試更新'全局變量',我們會遇到併發問題?threadlocal變量如何與方法級別變量不同

我的另一個問題是:如果我在一個方法中聲明瞭一個變量,那麼在它自己的堆棧中執行該方法的每個線程都將獲得它自己的副本。那麼聲明一個方法級別的變量就像使threadlocal一樣?

+0

局部變量始終是線程安全的。對於'線程局部變量'檢查了這一點:http://stackoverflow.com/questions/817856/when-and-how-should-i-use-a-threadlocal-variable – Shivam

+0

線程本地的主要特點是什麼? – Val

回答

3

第一個問題:每個線程更新其threadlocal變量的副本,線程之間不共享全局狀態。第二個問題:如果聲明本地變量,它的行爲與threadlocal相似 - 每個線程都有自己的副本,但是您沒有全局訪問權限,例如,在另一種方法 - 這是threadlocal是有用的。

+0

感謝您的簡潔回答! – Victor

0

有關ThreadLocal變量的重要一點是全局訪問。它可以從thread.inside中的任何地方訪問任何在該線程上下文中調用的方法。

如果你想爲一個類的所有實例維護一個變量的單個實例,你將使用靜態類成員變量來完成它。如果你想在每個線程的基礎上維護一個變量的實例,你將使用線程局部變量。 ThreadLocal變量不同於普通變量,因爲每個線程都有自己獨立初始化的變量實例,它通過get()或set()方法訪問它。

假設您正在開發一個多線程代碼跟蹤器,其目標是通過您的代碼唯一標識每個線程的路徑。挑戰在於你需要在多個線程中的多個類中協調多個方法。沒有ThreadLocal,這將是一個複雜的問題。當一個線程開始執行時,它需要生成一個唯一的標記以在跟蹤器中標識它,然後將該唯一標記傳遞給跟蹤中的每個方法。

使用ThreadLocal,事情更簡單。線程在執行開始時初始化線程局部變量,然後從每個類中的每個方法訪問它,並保證該變量僅託管當前正在執行的線程的跟蹤信息。當它完成執行時,線程可以將其線程特定的跟蹤傳遞給負責維護所有跟蹤的管理對象。

當你需要在每個線程的基礎上存儲變量實例時,使用ThreadLocal是有意義的。

+0

如果它們具有對'ThreadLocal'對象的引用。 –

1

看一個ThreadLocal<T>對象最簡單的方法是爲Map<Thread, T>,其中ThreadLocal#get()通話將被調用底層MapMap#get(Thread.currentThread())查找適當的值。請注意,這不是實際的實現,而是最簡單的方法來查看它。

ThreadLocal變量只能用作實際可以被多個線程同時訪問的成員。方法中變量的局部聲明只是本地聲明,因此其他線程無法訪問。我不會說他們是'一樣的',但他們都是線程安全的。

典型用法是多線程環境中單例對象的實例成員變量或類的靜態成員變量。

大多數情況下,您會看到它們用於在servlet環境中傳遞請求上下文信息。

0

如果我使用一個ThreadLocal變量,則每個線程的 變量

我認爲這是關於可變期限本地拷貝一些cunfusion本地副本。沒有副本。每個線程都有自己的變量;這些是彼此獨立的。但是,這並不意味着他們無法持有對共享對象的引用。所以,僅僅使用threadlocal變量並不能解決併發問題。

關於你的第二個問題:不。局部變量和threadlocal變量是不同的。局部變量不能在定義它們的塊之外訪問。因此,例如,調用相同的方法兩次將導致每次都有不同的值。另一方面,只要線程存在,threadlocal變量就會保留它們的值。

基本上,threadlocal變量是一種單個線程的'靜態'變量。