Una delle difficolta' maggiori nell'ambito della programmazione e' l'aspetto legato ai thread. Senza entrare troppo nel merito del loro funzionamento, chiunque si sia cimentato in questo campo conoscera' benissimo la pericolosita' dei deadlock o i problemi che sorgono dal dover usare risorse sincronizzate.
Affrontando l'argomento in java si e' forse un po' piu' avvantaggiati, rispetto ad altri linguaggi, dagli strumenti messi a disposizione della Java virtual Macchine (jvm), come ad esempio i metodi syncronized. Ma spesso chi si avvicina a questo ambiente, nel caso piu' comune attraverso gli application server, incappa in un errore non troppo comprensibile a meno di non conoscere bene i meccanismi di gestione di memoria della jvm. L'errore e' semplice, si utilizzano in diversi thread concorrenti le stesse variabili statiche per salvare dei dati. questo fa si che in un pezzo di codice non sincronizzato non si puo' assumere che il valore della variabile statica resti costante in quanto un'altro thread potrebbe accedervi e modificarla.
Quando e' stato affrontato questo problema in relazione al mondo del web e ai vari Application server, per ovviare alla necessita' di avere una locazione di memoria "globale" ma differenziata per ogni thread (o per ogni richiesta) e' nata l'idea di sessione, ovvero uno spazio di memoria indicizzata e accessibile solo attraverso una chiave. Ogni thread avra' quindi una chiave univoca e quindi il suo spazio riservato.
Questo e' il metodo piu' semplice, efficace ed utilizzato per passare dei valori all'interno di un workflow fatto di servet successive (esempi piu' comuni sono il login per aree riservate o i carrelli per i siti di e-commerce).
Portando un esempio con Tomcat e le servlet, si accede a questa sessione attraverso un metodo della HttpRequest e su questa sessione e' possibile utilizzare metodi di put e get per aggiungere o richiedere dati.
Esiste pero' un altro modo per legare variabili ai vari thread, senza far si che queste soffrano di problemi di concorrenza, questo metodo e' generalmente definito Thread Local Storage (TLS). L'implementazione di questo tipo di memoria fa si che variabili statiche di questa classe non siano scritte nell'heap della jvm (come tutti i riferimenti statici) ma bensi nello stack di ogni singolo thread. Il risultato e' una variabile statica locale al singolo thread e quindi sicura ed utilizzabile per imagazzinare valori stabili al cambiare di metodi.
Per utilizzare questa funzionalita' in java e' sufficiente dichiarare una variabile statica di tipo ThreadLocal<T?> che specifici con i generics (nel caso di java 5+) il tipo di classe referenziata, ad esempio
public static ThreadLocal<String> username;
Avremo quindi a dispoizione due metodi, username.set(String) e username.get() per impostare e recuperare il valore dell'istanza di String che rappresenta il dato che vogliamo raggiungere.
Un implementazione molto utile di questa classe e' quella di usarla in combinazione ad una servlet base (una classe astratta) che valorizzi ad ogni richiesta (e quindi tendenzialmente in un thread differente) un oggeto statico ThreadLocal che contenga i dati generici che ci serviranno (ad esempio l'username o altre cose legate all'utente) e che poi richiami il codice della pagina (un'implementazione di questa classe astratta) che potra' quindi fare riferimento a questo metodo statico per recuperare dati relativi all'utente, senza passare dalla HttpRequest (o ServletRequest, o ActionRequest etc..).
Questo fa si che se si sviluppa uno strato di business logic che ha bisogno esteso di accedere ai dati dell'utente, sia possibile farlo senza dover tutte le volte, nelle servlet recuperare tutti questi dati o ancora peggio passare la sessione come argomento del metodo di business (legando cosi' indissolubilmente il nostro strato di business ad un'interfaccia web based).