ThreadLocal zapewni dostęp do obiektu zmiennego przez wiele wątków w niezsynchronizowanej metodzie jest zsynchronizowany, co oznacza, że obiekt zmienny będzie niezmienny w obrębie metody.
Osiąga się to poprzez podanie nowej instancji obiektu zmiennego dla każdej próby uzyskania dostępu do wątku. Jest to lokalna kopia dla każdego wątku. Jest to pewien hack przy tworzeniu zmiennej instancji w metodzie dostępnej jak zmienna lokalna. Ponieważ wiesz, że zmienna lokalna metody jest dostępna tylko dla wątku, jedną różnicą jest; zmienne lokalne metody nie będą dostępne dla wątku po zakończeniu wykonywania metody, w której obiekt zmienny współdzielony z Threadlocal będzie dostępny dla wielu metod, dopóki go nie wyczyścimy.
Zgodnie z definicją:
Klasa ThreadLocal w Javie umożliwia tworzenie zmiennych, które mogą być odczytywane i zapisywane tylko przez ten sam wątek. Dlatego nawet jeśli dwa wątki wykonują ten sam kod, a kod zawiera odwołanie do zmiennej ThreadLocal, wówczas oba wątki nie widzą nawzajem swoich zmiennych ThreadLocal.
Każda Thread
w java zawiera ThreadLocalMap
w sobie.
Gdzie
Key = One ThreadLocal object shared across threads.
value = Mutable object which has to be used synchronously, this will be instantiated for each thread.
Osiągnięcie ThreadLocal:
Teraz stwórz klasę opakowania dla ThreadLocal, która będzie przechowywać zmienny obiekt jak poniżej (z lub bez initialValue()
).
Teraz getter i setter tego opakowania będą działały na instancji Threadlocal zamiast obiektu mutable.
Jeśli getter () z Threadlocal nie znalazł żadnej wartości z w Threadlocalmap na Thread
; następnie wywoła funkcję initialValue (), aby uzyskać swoją prywatną kopię dotyczącą wątku.
class SimpleDateFormatInstancePerThread {
private static final ThreadLocal<SimpleDateFormat> dateFormatHolder = new ThreadLocal<SimpleDateFormat>() {
@Override
protected SimpleDateFormat initialValue() {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd") {
UUID id = UUID.randomUUID();
@Override
public String toString() {
return id.toString();
};
};
System.out.println("Creating SimpleDateFormat instance " + dateFormat +" for Thread : " + Thread.currentThread().getName());
return dateFormat;
}
};
/*
* Every time there is a call for DateFormat, ThreadLocal will return calling
* Thread's copy of SimpleDateFormat
*/
public static DateFormat getDateFormatter() {
return dateFormatHolder.get();
}
public static void cleanup() {
dateFormatHolder.remove();
}
}
Teraz wrapper.getDateFormatter()
zadzwoni threadlocal.get()
i sprawdzi, czy currentThread.threadLocalMap
zawiera to wystąpienie (Threadlocal).
Jeśli tak, zwróć wartość (SimpleDateFormat) dla odpowiedniej
instancji Threadlocal, w przeciwnym razie dodaj mapę z tą instancją ThreadLocal, initialValue ().
W ten sposób osiągnięto bezpieczeństwo wątków w tej klasie zmiennych; przez każdy wątek działa z własną instancją mutable, ale z tą samą instancją ThreadLocal. Oznacza, że cały wątek będzie współdzielił tę samą instancję ThreadLocal jako klucz, ale inną instancję SimpleDateFormat jako wartość.
https://github.com/skanagavelu/yt.tech/blob/master/src/ThreadLocalTest.java