2012-06-25 13 views
6

Ho appena saputo di ThreadLocal questa mattina. Ho letto che dovrebbe sempre essere finale e statico come:Confuso su ThreadLocal

private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); 

(Session è una sessione Hibernate)

La mia confusione è questa: Perché è statica, è disponibile a qualsiasi discussione nella JVM. Tuttavia conserverà le informazioni locali per ogni thread che le accede? Sto cercando di spiegarmelo, quindi mi scuso se non è chiaro. Ogni thread nell'applicazione ha accesso allo stesso oggetto ThreadLocal, ma l'oggetto ThreadLocal memorizzerà gli oggetti locali su ciascun thread?

+3

Attenzione all'utilizzo di questo nelle applicazioni Web distribuite in un ambiente condiviso. Il thread locale si diffonderà in tutti i contesti e, dopo averlo annullato, i riferimenti nel thread locale non verranno eliminati. È necessario rimuovere manualmente i dati dopo ogni richiesta. – jontro

+0

È apparentemente contraddittorio. 'ThreadLocal' dovrebbe essere unico in ogni thread, ma gli oggetti statici sono condivisi tra ogni thread. Stavo per fare la stessa domanda. – aliteralmind

risposta

10

Sì, l'istanza sarebbe la stessa, ma il codice allega il valore impostato con lo Thread.currentThread(), quando si imposta e quando si recupera, quindi il set di valori sarà accessibile solo all'interno del thread corrente quando si accede utilizzando i metodi set e get.

È davvero facile da capire.

Immaginate che ogni Thread abbia una mappa che associa un valore a un'istanza ThreadLocal. Ogni volta che esegui un risultato o un set su ThreadLocal, l'implementazione di ThreadLocal ottiene la mappa associata all'attuale Thread (Thread.currentThread()) ed esegue lo get o set in quella mappa utilizzando se stesso come chiave.

Esempio:

ThreadLocal tl = new ThreadLocal(); 
tl.set(new Object()); // in this moment the implementation will do something similar to Thread.getCurrentThread().threadLocals.put(tl, [object you gave]) 

Object obj = t1.get(); // in this moment the implementation will do something similar to Thread.getCurrentThread().threadLocals.get(tl) 

E la cosa interessante di questo è che il ThreadLocal è gerarchica, nel senso se è stato definito un valore per un genitore Thread sarà accessibile da un bambino uno.

+0

Grazie, questo aiuta molto. – badgerduke

+0

Siete i benvenuti! –

+0

Dici, immagina che ci sia una mappa nel 'ThreadLocal'. Ho capito il concetto. L'id del thread è la chiave, le istanze univoche sono i valori. Quindi l'oggetto 'ThreadLocal' generale è statico e contiene un valore per thread. In realtà è implementato con una mappa interna? – aliteralmind

2

Si accede sempre alla stessa istanza di ThreadLocal per un problema specifico ma questa istanza restituisce un valore diverso per ogni thread che chiama il metodo get.

Questo è il punto: è facile trovare l'oggetto ma ogni thread avrà il suo specifico valore. Pertanto, ad esempio, è possibile assicurarsi che il proprio valore specifico non sia accessibile da due thread diversi.

Si poteva vedere (concettualmente) come una specie di HashMap<Thread><V> a cui si accedeva sempre con Thread.currentThread() come chiave.

+0

Grazie per la risposta! – badgerduke

2

Poiché i valori specifici del filetto non sono memorizzati nell'oggetto ThreadLocal, ma lo ThreadLocalMapThreadLocalMapcurrent Thread. L'oggetto ThreadLocal funge semplicemente da chiave in queste mappe.

Per i dettagli, leggere il JavaDoc di ThreadLocal e le sottoclassi, oppure, se si è interessati all'implementazione, il codice sorgente disponibile in tutti i JDK recenti src.zip.

+0

Grazie, questo ha aiutato! – badgerduke