ThreadLocal bedeutet Thread-lokale Variable! Was sind also lokale Thread-Variablen? Was nützt dieses Ding? Liegt es daran, dass Sie in einem Vorstellungsgespräch gefragt wurden und mir nichts sagen konnten? Werfen wir heute einen Blick auf den Quellcode dieses Produkts und verstehen wir grundlegend, was es tut.
Die Beziehung zwischen Thread, ThreadLocalMap und Entry
Tatsächlich ist es nach dem Studium seiner Quellcode-Implementierung tatsächlich nicht so Wie kompliziert, sind die Hauptpunkte wie folgt:
1. Java kann das aktuelle Thread-Instanzobjekt über Thread.currentThread() abrufen. Da wir nun die Thread-Objektinstanz erhalten können, können wir die Instanz (Eigenschaften) bedienen, beispielsweise einen Wert für das Thread-Objekt festlegen.
2. Jedes Thread-Objekt verfügt über eine ThradLocalMap-Instanz, die über zwei Hauptattribute verfügt: Wert und schwache Referenz auf ThreadLocal, wobei das Wertattribut die Werteinstellung ist vom aktuellen Thread und ist auch das Kernattribut von ThreadLocal:
static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
Beachten Sie, dass Entry von WeakReference erbt und sein Schlüssel das ThreadLocal-Objekt ist! (Abbildung 1)
Durch die Kombination der beiden Wissenspunkte 1 und 2 können wir wissen, dass wir nach Erhalt des Thread-Objekts das ThreadLocalMap-Objekt des aktuellen Thread-Objekts steuern können Geben Sie dann den Wert ein, den Sie im Wertattribut von ThreadLocalMap speichern möchten. Die Beziehung zwischen Thread, ThreadLocalMap und Wert kann durch die folgende Abbildung dargestellt werden (Abbildung 2):
Aus der obigen Abbildung können wir die Schlussfolgerung ziehen: Ein Thread-Objekt enthält ein ThreadLocalMap-Objekt, und dann enthält ein ThreadLoalMap-Objekt mehrere ThreadLlocal-Objekte und den Wert des Threads, in dem sich das ThreadLocal-Objekt befindet! ! ! Kurz gesagt: Ein Thread-Objekt kann die Variablenwerte mehrerer ThreadLocal-Objekte enthalten.
Wie ist also die Beziehung zwischen ThreadLocal und Thread? Wie können die beiden den Wert ablesen? Nachfolgend finden Sie eine kurze Analyse basierend auf dem Quellcode.
Die Beziehung zwischen ThreadLocal und Thread
Erster Blick auf die Set-Methode von ThreadLocal:
public void set(T value) { //获取当前线程 Thread t = Thread.currentThread(); //获取当前线程持有的ThreadLocalMap ThreadLocal.ThreadLocalMap map = getMap(t); //将value设置给threadlocalMap if (map != null) map.set(this, value); else createMap(t, value); }
Die Set-Methode ist sehr logisch und einfach (j kombiniert mit Abbildung 2 oben (siehe zum besseren Verständnis):
1. Holen Sie sich das aktuelle Thread-Objekt über die currentThread-Methode
2. Holen Sie sich das ThreadLoalMap-Objekt des aktuellen Thread-Objekts
3. Kombinieren Sie den Wert mit dem ThreadLocal-Objekt. Bilden Sie selbst ein Entry-Objekt und speichern Sie es im Entry-Typ-Array von
ThreadLoalMap.
Werfen wir einen Blick auf die get-Methode von ThreadLocal:
public T get() { //获取当前线程 Thread t = Thread.currentThread(); //获取当前线程的ThreadLocalMap对象 ThreadLocalMap map = getMap(t); if (map != null) { //获取与ThreadLocal对象想关联的value ThreadLocalMap.Entry e = map.getEntry(this); if (e != null) { @SuppressWarnings("unchecked") //获取值 T result = (T)e.value; return result; } } //为空返回初始化值 return setInitialValue(); }
Die Gesamtlogik von get kann entwickelt werden und ist auch sehr einfach:
1. Aktuelles Thread-Objekt abrufen
2. ThreadLocalMap-Objekt des aktuellen Thread-Objekts abrufen
3. Das mit ThreadLocal verknüpfte Entry-Objekt von ThreadLocalMap abrufen, insbesondere ThreadLocal als verwenden Schlüssel.
4. Rufen Sie das Wertattribut des Eintrags in Schritt 3 ab und geben Sie es zurück.
Durch die Betrachtung der get- und set-Methoden als Ganzes können wir die folgenden Schlussfolgerungen ziehen: Das ThreadLocal-Objekt ruft die set-Methode auf, um der ThreadLocalMap des Thread-Objekts einen Wert hinzuzufügen; das ThreadLocal-Objekt ruft die get-Methode auf, um die zu erhalten Wert aus der ThreadLocalMap des Thread-Objekts. Der Kern besteht darin, das ThreadLocalMap-Objekt des Thread-Objekts zu manipulieren, um Werte zu lesen und zu schreiben. Das Prinzip ist so einfach.
Wie ist also die Beziehung zwischen verschiedenen ThreadLocal-Objekten, die sich in verschiedenen Threads befinden, und dem Speichern von Werten in anderen Threads? Es kann durch das folgende Bild klar beschrieben werden:
Verwendungsbeispiele von ThreadLocal
Wir wissen, dass es in Android nur A gibt Looper-Objekt, wie wird es gemacht? Es ist ThreadLocal, das eine Rolle spielt:
//定义一个静态的ThreadLocal变量 static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>(); private static void prepare(boolean quitAllowed) { //一个Thread只能关联一个Looper对象 if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
Sie können anhand der Prepare-Methode feststellen, ob der aktuelle Thread bereits über einen Looper verfügt Wenn ja, werfen Sie eine Ausnahme aus. Wenn der aktuelle Thread kein Looper-Objekt festgelegt hat, rufen Sie die Set-Methode von ThreadLocal auf, um ein Looper-Objekt zu initialisieren und es an den aktuellen Thread zu übergeben Ein Thread hat nur ein Looper-Objekt.
Bisher wurde das Prinzip von ThreadLocal im Wesentlichen analysiert. Was die interne Einstellung und den Zugriff angeht, hat der Blogger keine allzu detaillierte Analyse durchgeführt, da es nicht notwendig ist, die Arbeitsgründe und Verwendungsszenarien von ThreadLocal zu verstehen . Das ist es.
Das obige ist der detaillierte Inhalt vonEine kurze Analyse des ThreadLocal-Prinzips. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!