Heim Java javaLernprogramm Die Verwendung von ThreadLocal im Java-Multithreading

Die Verwendung von ThreadLocal im Java-Multithreading

Oct 17, 2018 pm 04:21 PM
java 多线程

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 Verwendung von ThreadLocal im Java-Multithreading

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>
Nach dem Login kopieren

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>
Nach dem Login kopieren

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;
Nach dem Login kopieren

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>
Nach dem Login kopieren

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>
Nach dem Login kopieren

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!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Perfekte Zahl in Java Perfekte Zahl in Java Aug 30, 2024 pm 04:28 PM

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

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

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.

Smith-Nummer in Java Smith-Nummer in Java Aug 30, 2024 pm 04:28 PM

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

Fragen zum Java Spring-Interview Fragen zum Java Spring-Interview Aug 30, 2024 pm 04:29 PM

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.

Brechen oder aus Java 8 Stream foreach zurückkehren? Brechen oder aus Java 8 Stream foreach zurückkehren? Feb 07, 2025 pm 12:09 PM

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

Zeitstempel für Datum in Java Zeitstempel für Datum in Java Aug 30, 2024 pm 04:28 PM

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.

Java -Programm, um das Kapselvolumen zu finden Java -Programm, um das Kapselvolumen zu finden Feb 07, 2025 am 11:37 AM

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

Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Gestalten Sie die Zukunft: Java-Programmierung für absolute Anfänger Oct 13, 2024 pm 01:32 PM

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.

See all articles