Java ThreadLocal wird verwendet, um threadlokale Variablen zu erstellen. Wir wissen, dass alle Threads eines Objekts dessen Variablen teilen, sodass die Variable nicht threadsicher ist. Wir können Synchronisation für Threadsicherheit verwenden, aber wenn wir die Synchronisation vermeiden wollen, können wir ThreadLocal
Variablen verwenden.
Java ThreadLocal
Jeder Thread hat seine eigene
ThreadLocal
Variable und sie können ihre get() und set() Methoden verwenden, um den Standardwert zu erhalten oder ihren Wert lokal zum Thread zu ändern. ThreadLocal-Instanzen sind typischerweise private statische Felder in Klassen, die einen Zustand mit einem Thread verknüpfen möchten.
Java ThreadLocal Beispiel
Hier ist ein kleines Beispiel, das die Verwendung von ThreadLocal in einem Java-Programm zeigt und beweist, dass jeder Thread seine eigene Kopie der ThreadLocal-Variablen hat. ThreadLocalExample.java
package com.journaldev.threads;
import java.text.SimpleDateFormat;
import java.util.Random;
public class ThreadLocalExample implements Runnable{
// SimpleDateFormat ist nicht thread-sicher, also geben Sie jedem Thread einen
private static final ThreadLocal formatter = new ThreadLocal(){
@Override
protected SimpleDateFormat initialValue()
{
return new SimpleDateFormat("yyyyMMdd HHmm");
}
};
public static void main(String[] args) throws InterruptedException {
ThreadLocalExample obj = new ThreadLocalExample();
for(int i=0 ; i<10; i++){
Thread t = new Thread(obj, ""+i);
Thread.sleep(new Random().nextInt(1000));
t.start();
}
}
@Override
public void run() {
System.out.println("Thread Name= "+Thread.currentThread().getName()+" default Formatter = "+formatter.get().toPattern());
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
//Das Formatmuster wird hier vom Thread geändert, aber es wird sich nicht auf andere Threads auswirken
formatter.set(new SimpleDateFormat());
System.out.println("Thread Name= "+Thread.currentThread().getName()+" formatter = "+formatter.get().toPattern());
}
}
Die Ausgabe des oben genannten Java ThreadLocal Beispielprogramms ist:
Thread Name= 0 default Formatter = yyyyMMdd HHmm
Thread Name= 1 default Formatter = yyyyMMdd HHmm
Thread Name= 0 formatter = M/d/yy h:mm a
Thread Name= 2 default Formatter = yyyyMMdd HHmm
Thread Name= 1 formatter = M/d/yy h:mm a
Thread Name= 3 default Formatter = yyyyMMdd HHmm
Thread Name= 4 default Formatter = yyyyMMdd HHmm
Thread Name= 4 formatter = M/d/yy h:mm a
Thread Name= 5 default Formatter = yyyyMMdd HHmm
Thread Name= 2 formatter = M/d/yy h:mm a
Thread Name= 3 formatter = M/d/yy h:mm a
Thread Name= 6 default Formatter = yyyyMMdd HHmm
Thread Name= 5 formatter = M/d/yy h:mm a
Thread Name= 6 formatter = M/d/yy h:mm a
Thread Name= 7 default Formatter = yyyyMMdd HHmm
Thread Name= 8 default Formatter = yyyyMMdd HHmm
Thread Name= 8 formatter = M/d/yy h:mm a
Thread Name= 7 formatter = M/d/yy h:mm a
Thread Name= 9 default Formatter = yyyyMMdd HHmm
Thread Name= 9 formatter = M/d/yy h:mm a
Wie Sie aus der Ausgabe sehen können, hat Thread-0 den Wert des Formatters geändert, aber der Standardformatter von Thread-2 ist immer noch derselbe wie der initialisierte Wert. Sie können das gleiche Muster auch für andere Threads sehen. Aktualisierung: Die ThreadLocal-Klasse wird in Java 8 mit einer neuen Methode withInitial()
erweitert, die das Supplier-Funktionsinterface als Argument verwendet. Wir können Lambda-Ausdrücke verwenden, um die ThreadLocal-Instanz einfach zu erstellen. Zum Beispiel kann die obige Formatter-ThreadLocal-Variable in einer Zeile wie folgt definiert werden:
private static final ThreadLocal<SimpleDateFormat> formatter =
ThreadLocal.<SimpleDateFormat>withInitial
(() -> {return new SimpleDateFormat("yyyyMMdd HHmm");});
Wenn Sie neu in den Funktionen von Java 8 sind, sehen Sie sich bitte Java 8-Funktionen und Java 8-Funktionsschnittstellen an. Das ist alles für ThreadLocal in der Java-Programmierung. Referenz: API-Dokumentation
Source:
https://www.digitalocean.com/community/tutorials/java-threadlocal-example