Die Verwendung von ThreadLocal im Java-Multithreading
Der Inhalt dieses Artikels befasst sich mit der Verwendung von ThreadLocal im Java-Multithreading. Ich hoffe, dass er für Freunde hilfreich ist.
In einer Multithread-Umgebung muss die Thread-Synchronisierung durchgeführt werden, wenn auf nicht-threadsichere Variablen zugegriffen wird, z. B. wenn die synchronized
-Methode verwendet wird, um auf HashMap
-Instanzen zuzugreifen. Allerdings verringert der synchrone Zugriff die Parallelität und beeinträchtigt die Systemleistung. Zu diesem Zeitpunkt können Sie Platz gegen Zeit eintauschen. Wenn wir jedem Thread eine unabhängige Variable zuweisen, können Sie nicht-thread-sichere Variablen asynchron verwenden. Wir nennen solche Variablen Thread-lokale Variablen.
Wie der Name schon sagt, bedeuten lokale Thread-Variablen, dass jeder Thread seine eigene unabhängige Kopie der Variablen hat, auf die andere Threads nicht wie gewöhnliche lokale Variablen zugreifen können. Java
stellt keine lokalen Thread-Variablen auf Sprachebene bereit, stellt jedoch die Funktion lokaler Thread-Variablen in der Klassenbibliothek bereit, die diesmal die Protagonistenklasse ThreadLocal
ist.
Verwendung von ThreadLocal
Die Java8-Version von ThreadLocal hat 4, wie im gezeigt Bild oben Es gibt zwei öffentliche Methoden und eine geschützte Methode. Die erste Methode wird verwendet, um den Anfangswert zurückzugeben, der standardmäßig null ist. Die zweite statische Methode withInitial(Supplier erweitert S> Lieferant) wurde in der Java8-Version neu hinzugefügt, und die nächsten drei Instanzmethoden sind sehr einfach.
Wenn Sie ThreadLocal verwenden und den Anfangswert festlegen möchten, müssen Sie die ThreadLocal-Klasse erben und die geschützte T initialValue()-Methode überschreiben. Beispiel:
ThreadLocal<integer> threadLocal = new ThreadLocal<integer>() { @Override protected Integer initialValue() { return 0; } };</integer></integer>
kann in der Java8-Version verwendet werden. Die neu hinzugefügte statische Methode withInitial(Supplier erweitert S> Lieferant) ist sehr praktisch, um den Anfangswert festzulegen, zum Beispiel:
ThreadLocal<integer> threadLocal = ThreadLocal.withInitial(() -> 0); System.out.println(threadLocal.get()); threadLocal.set(16); System.out.println(threadLocal.get()); threadLocal.remove(); System.out.println(threadLocal.get()); // 同一个线程的输出 0 16 0 Process finished with exit code 0</integer>
Das Prinzip von ThreadLocal
Dann ist ThreadLocal Wie implementiert man die Funktion lokaler Thread-Variablen? Tatsächlich ist das Grundprinzip von ThreadLocal nicht sehr kompliziert. ThreadLocal definiert intern eine statische Klasse ThreadLocalMap. Der Wert von ThreadLocalMap ist der von ThreadLocal gespeicherte Wert. Schauen wir uns einen Teil des Quellcodes von ThreadLocal an:
// ThreadLocal的set方法 public void set(T value) { // 获取当前线程对象 Thread t = Thread.currentThread(); // 获取Map ThreadLocalMap map = getMap(t); if (map != null) // 设置值 map.set(this, value); else // 初始化Map createMap(t, value); } // ThreadLocal的createMap方法 void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); } // Thread类定义的实例域 /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */ ThreadLocal.ThreadLocalMap threadLocals = null;
Es ist ersichtlich, dass die Kernimplementierung von ThreadLocal die Implementierung von ThreadLocalMap ist, die intern eine Entry-Klasse zum Speichern von Daten deklariert:
static class Entry extends WeakReference<threadlocal>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal> k, Object v) { super(k); value = v; } }</threadlocal>
ThreadLocalMap-Implementierung Es gibt Ähnlichkeiten mit der Implementierung von HashMap. Beispielsweise werden Arrays auch zum Speichern von Daten und zur automatischen Erweiterung verwendet. Der Unterschied besteht darin, dass der Hash-Algorithmus und die Verarbeitung nach der Hash-Kollision unterschiedlich sind.
// ThreadLocalMap的set方法 private void set(ThreadLocal> key, Object value) { Entry[] tab = table; int len = tab.length; // 计算在Entry[]中的索引,每个ThreadLocal对象都有一个hash值threadLocalHashCode,每初始化一个ThreadLocal对象,hash值就增加一个固定的大小0x61c88647 int i = key.threadLocalHashCode & (len-1); for (Entry e = tab[i]; e != null; e = tab[i = nextIndex(i, len)]) { ThreadLocal> k = e.get(); // 如果键已存在就更新值 if (k == key) { e.value = value; return; } // 代替无效的键 if (k == null) { replaceStaleEntry(key, value, i); return; } } tab[i] = new Entry(key, value); int sz = ++size; if (!cleanSomeSlots(i, sz) && sz >= threshold) rehash(); } private static int nextIndex(int i, int len) { return ((i + 1 <p>Sie können sehen, dass ThreadLocalMap das Array Entry[] als Ring behandelt. Wenn der Index ausgehend von der berechneten Indexposition bereits Daten enthält, wird beurteilt, ob der Schlüssel derselbe ist, und wenn er identisch ist, wird der Wert aktualisiert. Andernfalls warten Sie einfach, bis Sie eine leere Position gefunden haben, und geben Sie dort den Wert ein. Das Gleiche gilt, wenn Sie ausgehend von der berechneten Indexposition prüfen, ob die Schlüssel nacheinander gleich sind. Wenn es viele Hash-Kollisionen gibt, ist die Leistung möglicherweise nicht sehr gut. </p><p><strong>ThreadLocal application</strong><code><code><br></code></code></p><p><code><span style="font-family: Microsoft YaHei, Microsoft YaHei; "> ThreadLocal wird häufig verwendet. Das Spring-Framework, mit dem Java-Ingenieure sehr vertraut sind, verwendet ThreadLocal, um nicht threadsichere zustandsbehaftete Objekte zu kapseln, sodass wir die meisten Beans als Singleton-Bereich deklarieren können. Wenn wir Multithread-Code schreiben, können wir auch darüber nachdenken, ob es besser ist, synchron auf nicht-threadsichere zustandsbehaftete Objekte zuzugreifen oder ob es besser ist, ThreadLocal zum Kapseln nicht-threadsicherer zustandsbehafteter Objekte zu verwenden. <code><span style="font-family: 微软雅黑, Microsoft YaHei;">ThreadLocal的应用是非常广的,比如Java工程师非常熟悉的Spring框架中就使用了ThreadLocal来把非线程安全的状态性对象封装起来,所以我们可以把绝大部分的Bean声明为singleton作用域。我们在编写多线程代码时也可以想想是用同步的方式访问非线程安全的状态性对象比较好,还是使用ThreadLocal把非线程安全的状态性对象封装起来更好。</span><br></code></span></code></p><p class="comments-box-content"><br></p>
Das obige ist der detaillierte Inhalt vonDie Verwendung von ThreadLocal im Java-Multithreading. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Leitfaden zur perfekten Zahl in Java. Hier besprechen wir die Definition, Wie prüft man die perfekte Zahl in Java?, Beispiele mit Code-Implementierung.

Leitfaden für Weka in Java. Hier besprechen wir die Einführung, die Verwendung von Weka Java, die Art der Plattform und die Vorteile anhand von Beispielen.

Leitfaden zur Smith-Zahl in Java. Hier besprechen wir die Definition: Wie überprüft man die Smith-Nummer in Java? Beispiel mit Code-Implementierung.

In diesem Artikel haben wir die am häufigsten gestellten Fragen zu Java Spring-Interviews mit ihren detaillierten Antworten zusammengestellt. Damit Sie das Interview knacken können.

Java 8 führt die Stream -API ein und bietet eine leistungsstarke und ausdrucksstarke Möglichkeit, Datensammlungen zu verarbeiten. Eine häufige Frage bei der Verwendung von Stream lautet jedoch: Wie kann man von einem Foreach -Betrieb brechen oder zurückkehren? Herkömmliche Schleifen ermöglichen eine frühzeitige Unterbrechung oder Rückkehr, aber die Stream's foreach -Methode unterstützt diese Methode nicht direkt. In diesem Artikel werden die Gründe erläutert und alternative Methoden zur Implementierung vorzeitiger Beendigung in Strahlverarbeitungssystemen erforscht. Weitere Lektüre: Java Stream API -Verbesserungen Stream foreach verstehen Die Foreach -Methode ist ein Terminalbetrieb, der einen Vorgang für jedes Element im Stream ausführt. Seine Designabsicht ist

Anleitung zum TimeStamp to Date in Java. Hier diskutieren wir auch die Einführung und wie man Zeitstempel in Java in ein Datum konvertiert, zusammen mit Beispielen.

Kapseln sind dreidimensionale geometrische Figuren, die aus einem Zylinder und einer Hemisphäre an beiden Enden bestehen. Das Volumen der Kapsel kann berechnet werden, indem das Volumen des Zylinders und das Volumen der Hemisphäre an beiden Enden hinzugefügt werden. In diesem Tutorial wird erörtert, wie das Volumen einer bestimmten Kapsel in Java mit verschiedenen Methoden berechnet wird. Kapselvolumenformel Die Formel für das Kapselvolumen lautet wie folgt: Kapselvolumen = zylindrisches Volumenvolumen Zwei Hemisphäre Volumen In, R: Der Radius der Hemisphäre. H: Die Höhe des Zylinders (ohne die Hemisphäre). Beispiel 1 eingeben Radius = 5 Einheiten Höhe = 10 Einheiten Ausgabe Volumen = 1570,8 Kubikeinheiten erklären Berechnen Sie das Volumen mithilfe der Formel: Volumen = π × R2 × H (4

Java ist eine beliebte Programmiersprache, die sowohl von Anfängern als auch von erfahrenen Entwicklern erlernt werden kann. Dieses Tutorial beginnt mit grundlegenden Konzepten und geht dann weiter zu fortgeschrittenen Themen. Nach der Installation des Java Development Kit können Sie das Programmieren üben, indem Sie ein einfaches „Hello, World!“-Programm erstellen. Nachdem Sie den Code verstanden haben, verwenden Sie die Eingabeaufforderung, um das Programm zu kompilieren und auszuführen. Auf der Konsole wird „Hello, World!“ ausgegeben. Mit dem Erlernen von Java beginnt Ihre Programmierreise, und wenn Sie Ihre Kenntnisse vertiefen, können Sie komplexere Anwendungen erstellen.
