ThreadLocal stellt sicher, dass der Zugriff auf das veränderbare Objekt durch die mehreren Threads in der nicht synchronisierten Methode synchronisiert wird. Dies bedeutet, dass das veränderbare Objekt innerhalb der Methode unveränderlich ist.
Dies wird erreicht, indem für jeden Thread, der versucht, darauf zuzugreifen, eine neue Instanz eines veränderlichen Objekts angegeben wird. Es ist also eine lokale Kopie für jeden Thread. Dies ist ein Hack, um Instanzvariablen in einer Methode, auf die zugegriffen werden soll, wie eine lokale Variable zu machen. Wie Sie wissen, ist die lokale Variable der Methode nur für den Thread verfügbar. Ein Unterschied besteht darin, Lokale Methodenvariablen stehen dem Thread nicht zur Verfügung, sobald die Methodenausführung abgeschlossen ist. Da das mit threadlocal gemeinsam genutzte veränderbare Objekt für mehrere Methoden verfügbar ist, bis wir es bereinigen.
Per Definition:
Mit der ThreadLocal-Klasse in Java können Sie Variablen erstellen, die nur von demselben Thread gelesen und geschrieben werden können. Selbst wenn zwei Threads denselben Code ausführen und der Code auf eine ThreadLocal-Variable verweist, können die beiden Threads die ThreadLocal-Variablen des anderen nicht sehen.
Jeder Thread
in Java enthält ThreadLocalMap
darin.
Wo
Key = One ThreadLocal object shared across threads.
value = Mutable object which has to be used synchronously, this will be instantiated for each thread.
Erreichen des ThreadLocal:
Erstellen Sie nun eine Wrapper-Klasse für ThreadLocal, die das veränderbare Objekt wie unten (mit oder ohne initialValue()
) enthält.
Jetzt arbeiten Getter und Setter dieses Wrappers mit einer threadlokalen Instanz anstelle eines veränderlichen Objekts.
Wenn getter () von threadlocal keinen Wert mit in der threadlocalmap von gefunden hat Thread
; dann ruft es den initialValue () auf, um seine private Kopie in Bezug auf den Thread zu erhalten.
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();
}
}
Nun wrapper.getDateFormatter()
rufen threadlocal.get()
und prüft das currentThread.threadLocalMap
enthält diese (Thread) Instanz.
Wenn ja, geben Sie den Wert (SimpleDateFormat) für die entsprechende threadlokale Instanz zurück,
andernfalls fügen Sie die Zuordnung mit dieser threadlokalen Instanz, initialValue (), hinzu.
Hiermit wurde die Fadensicherheit für diese veränderliche Klasse erreicht; Jeder Thread arbeitet mit seiner eigenen veränderlichen Instanz, jedoch mit derselben ThreadLocal-Instanz. Bedeutet, dass alle Threads dieselbe ThreadLocal-Instanz als Schlüssel verwenden, jedoch eine andere SimpleDateFormat-Instanz als Wert.
https://github.com/skanagavelu/yt.tech/blob/master/src/ThreadLocalTest.java