2010-10-18 29 views
8

Java中ThreadLocal的典型用法是什麼?什麼時候用它?我無法申請這篇java docs文章的詳細信息。ThreadLocal的使用

+2

可能重複[何時以及如何我應該使用一個ThreadLocal變量?](http://stackoverflow.com/questions/817856/when-and-how-should-i-use-a-threadlocal-變量) – YoK 2010-10-18 07:12:36

回答

4

適用於您希望使用非線程安全但不想同步對它們的訪問(出於性能原因)的對象。 或多或少,您爲需要多次使用的對象創建一個訪問器,以確保每個可能調用該訪問器的線程都獲得一個不同的未使用的對象。 一個非常典型的用法是使用SimpleDateFormat,它是一個類,如果它是線程安全的,那麼您的實例將被聲明爲靜態的,以便重用相同的實例。

下面是描述它的好文章:Dr. Dobbs: Using Thread-Local Variables In Java

4

也許更能說明問題的例子可以給你很好:

method1(): ... method2(somedata) ... 
method2(somedata): ... method3(somedata) ... 
method3(somedata): ... method4(somedata) ... 
method4(somedata): ... do something with somedata ... 

這種情況發生,例如在多層架構(UI調用遠程門面,遠程外觀調用應用程序層,應用程序層調用域圖層,域圖層調用持久層,...)如果這些方法()屬於不同的類,那麼除了爲我們的大多數方法添加額外參數「somedata」之外,沒有好方法來傳遞這些數據代碼,這打破了例如開閉原則。這個問題的解決方法是ThreadLocal的:

method1(): ... threadLocal.set(somedata); method2(); threadLocal.set(null); ... 
method2(): ... method3() ... 
method3(): ... method4() ... 
method4(): ... do something with threadLocal.get() ... 
5

我會說,最典型的ThreadLocal的使用是當你有一些對象,有一個流程中可以訪問無處不在,你不想通過參照本覆蓋所有圖層的對象。像單例模式,但每個線程。

這些示例是數據庫連接,hibernate會話等。您可以在流程開始的某個位置打開它們,在流程結束時提交/關閉並在流程中隨處使用。

0

如果您的流程與線程綁定在一起,如AlexR所述,您可以使用private static final ThreadLocal<T> p屬性創建public final class C,添加存取方法。然後你可以在你的流程中分別使用p.set(),p.remove()和p.get()。的

public final class C { 
    private static final ThreadLocal<String> p = new ThreadLocal<String>(); 

    // initialize property at the begining of your thread (flow) 
    public static void set(final String s){ 
     p.set(s); 
    } 

    // use property during the thread's lifecycle 
    // for instance: C.get().equals(myString) 
    public static String get(){ 
     return p.get(); 
    } 

    // remember to remove property from the thread when you're done, specially if it came from a thread pool 
    public static void remove(){ 
     p.remove(); 
    } 
}