2010-10-18 14 views
8

Qual è l'uso tipico di ThreadLocal in java. Quando lo si usa? Non ho potuto dettagli di applicazione da questo articolo java docs.Usi di ThreadLocal

+2

possibile duplicato di [Quando e come devo usare una variabile ThreadLocal?] (Http://stackoverflow.com/questions/817856/when-and-how-should-i-use-a-threadlocal- variabile) – YoK

risposta

4

È per quando si desidera utilizzare oggetti che non sono thread-safe, ma non si desidera sincronizzarne l'accesso (per motivi di prestazioni). Più o meno, si crea un accessor per l'oggetto che è necessario utilizzare più volte, in modo da garantire che ogni thread che potrebbe chiamare quell'accessor diventa diverso e non utilizzato. Un uso molto tipico è l'uso di SimpleDateFormat, che è una classe che, se fosse thread-safe, l'istanza sarebbe dichiarata statica, in modo da riutilizzare la stessa istanza.

Ecco un buon articolo descrivendolo: Dr. Dobbs: Using Thread-Local Variables In Java

4

esempio forse più illustrativo può essere buono per voi:

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

Tali situazioni si verificano ad esempio in architetture a più strati (UI chiama facciata a distanza, a distanza la facciata chiama il livello applicazione, il livello applicazione chiama livello dominio, livello dominio livello persistenza, ...) Se quei metodi() appartengono a classi diverse non c'è un buon modo per passare tali dati eccetto l'aggiunta di parametro aggiuntivo 'somedata' per la maggior parte dei metodi nel nostro codice, questo si rompe ad esempio principio aperto-chiuso. La soluzione a questo problema è ThreadLocal:

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

direi che il più tipico utilizzo ThreadLocal è quando si dispone di un oggetto che deve essere accessibile ovunque nel corso di una portata e non si vuole passare riferimento alla presente oggetto su tutti i livelli. Qualcosa come il modello singleton ma per thread.

Gli esempi sono DB connection, hibernate session ecc. Si aprono da qualche parte all'inizio del flusso, si esegue il commit/close alla fine del flusso e si utilizza ovunque durante il flusso.

0

Se il flusso è collegato a un thread, come menzionato da AlexR, è possibile creare un public final class C con una proprietà private static final ThreadLocal<T> p, aggiungere metodi di accesso. Quindi puoi usare p.set(), p.remove() e p.get() rispettivamente lungo il tuo flusso.

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