Ich habe hier den JavaDoc für Threadlocal gelesen
https://docs.oracle.com/javase/1.5.0/docs/api/java/lang/ThreadLocal.html
und es heißt "ThreadLocal-Instanzen sind normalerweise private statische Felder in Klassen, die den Status einem Thread zuordnen möchten (z. B. eine Benutzer-ID oder eine Transaktions-ID)."
Aber meine Frage ist, warum sie sich dafür entschieden haben, es statisch zu machen (normalerweise) - es macht die Dinge etwas verwirrend, den Status "pro Thread" zu haben, aber die Felder sind statisch?
quelle
ThreadLocal
, um einen Verweis auf einen Hash-Satz zu halten, der Objekte Instanzen pro Thread zuordnet.ThreadLocal
ihre eigenen threadlokalen Daten enthält, selbst wenn dieseThreadLocal
Instanzen im selben Thread vorhanden sind. Es ist nicht unbedingt falsch, das zu tun - ich nehme an, es ist vielleicht das am wenigsten populäre Muster der beidenMachen Sie es entweder statisch oder wenn Sie versuchen, statische Felder in Ihrer Klasse zu vermeiden - machen Sie die Klasse selbst zu einem Singleton, und dann können Sie ThreadLocal auf Instanzebene sicher verwenden, solange Sie dieses Singleton global verfügbar haben.
quelle
Das muss nicht sein. Das Wichtigste ist, dass es ein Singleton sein sollte.
quelle
Der Grund ist, dass auf die Variablen über einen dem Thread zugeordneten Zeiger zugegriffen wird. Sie verhalten sich wie globale Variablen mit Thread-Bereich, daher ist statisch die engste Anpassung. Auf diese Weise erhalten Sie den lokalen Thread-Status in Dingen wie pthreads, sodass dies möglicherweise nur ein Unfall der Historie und Implementierung ist.
quelle
Eine Verwendung für ein Threadlocal auf einer Instanz pro Thread besteht darin, dass etwas in allen Methoden eines Objekts sichtbar sein soll und es threadsicher sein soll, ohne den Zugriff darauf zu synchronisieren, wie Sie es für ein gewöhnliches Feld tun würden.
quelle
Beziehen Sie sich darauf , dies gibt ein besseres Verständnis.
Kurz gesagt,
ThreadLocal
Objekte funktionieren wie eine Schlüsselwertzuordnung. Wenn der Thread dieThreadLocal
get/set
Methode aufruft , werden das Thread-Objekt im Schlüssel der Karte und der Wert im Wert der Karte abgerufen / gespeichert. Aus diesem Grund haben verschiedene Threads unterschiedliche Wertkopien (die Sie lokal speichern möchten), da sie sich in verschiedenen Karteneinträgen befinden.Deshalb benötigen Sie nur eine Karte, um alle Werte beizubehalten. Obwohl dies nicht erforderlich ist, können Sie mehrere Zuordnungen (ohne statische Deklaration) verwenden, um auch jedes Thread-Objekt beizubehalten. Dies ist völlig redundant. Aus diesem Grund wird eine statische Variable bevorzugt.
quelle
static final ThreadLocal
Variablen sind threadsicher.static
stellt die ThreadLocal-Variable über mehrere Klassen hinweg nur für den jeweiligen Thread zur Verfügung. Es ist eine Art Dekaration globaler Variablen der jeweiligen lokalen Thread-Variablen über mehrere Klassen hinweg.Wir können die Sicherheit dieses Threads anhand des folgenden Codebeispiels überprüfen.
CurrentUser
- speichert die aktuelle Benutzer-ID in ThreadLocalTestService
- Einfacher Dienst mit Methode -getUser()
um den aktuellen Benutzer von CurrentUser abzurufen.TestThread
- Diese Klasse wird zum Erstellen mehrerer Threads und zum gleichzeitigen Festlegen von Benutzer-IDs verwendet.
.
.
Führen Sie die TestThread-Hauptklasse aus. Ausgabe -
Analysezusammenfassung
main
Die Ausführung endet und der aktuelle Benutzer wird als "62"ForkJoinPool.commonPool-worker-1
gedruckt. Die parallele Ausführung endet und der aktuelle Benutzer wird als "87"ForkJoinPool.commonPool-worker-2
gedruckt. Die parallele Ausführung endet und der aktuelle Benutzer wird als "31"ForkJoinPool.commonPool-worker-3
gedruckt. Die parallele Ausführung endet und der aktuelle Benutzer wird als "81" gedruckt.Inferenz
Concurrent Threads können korrekte Benutzer-IDs abrufen, selbst wenn sie als "statisch final ThreadLocal" deklariert wurden.
quelle