ThreadLocal signifie variable locale de thread ! Alors, que sont les variables locales du thread ? A quoi sert ce truc ? Est-ce qu’on vous a demandé lors d’un entretien et que vous n’avez rien pu me dire ? Aujourd'hui, examinons le code source de ce produit et comprenons fondamentalement ce qu'il fait.
La relation entre Thread, ThreadLocalMap et Entry
En fait, après avoir étudié l'implémentation de son code source, ce n'est en fait pas aussi aussi compliqué qu'on l'imagine, les points principaux sont les suivants :
1. Java peut obtenir l'objet d'instance Thread actuel via Thread.currentThread(). Maintenant que nous pouvons obtenir l'instance de l'objet Thread, nous pouvons utiliser l'instance (propriétés), par exemple définir une valeur pour l'objet Thread.
2. Chaque objet Thread possède une instance ThradLocalMap, qui possède un tableau d'entrées. L'objet Entry a deux attributs principaux : une valeur et une référence faible à ThreadLocal, où l'attribut value est le paramètre de valeur. par le thread actuel et est également l'attribut principal de ThreadLocal :
static class Entry extends WeakReference<ThreadLocal<?>> { /** The value associated with this ThreadLocal. */ Object value; Entry(ThreadLocal<?> k, Object v) { super(k); value = v; } }
Notez que Entry hérite de WeakReference et que sa clé est l'objet ThreadLocal ! (Figure 1)
En combinant les deux points de connaissance 1 et 2, nous pouvons savoir qu'après avoir obtenu l'objet Thread, nous pouvons contrôler l'objet ThreadLocalMap de l'objet thread actuel , puis donnez la valeur que vous souhaitez enregistrer dans l'attribut value de l'entrée de ThreadLocalMap. La relation entre Thread, ThreadLocalMap et la valeur peut être représentée par la figure suivante (Figure 2) :
<🎜. >
De la figure ci-dessus, nous pouvons tirer la conclusion : un objet Thread contient un objet ThreadLocalMap, et ensuite, un objet ThreadLoalMap contient plusieurs objets ThreadLlocal et la valeur du thread où se trouve l'objet ThreadLocal ! ! ! En un mot : un objet Thread peut contenir les valeurs variables de plusieurs objets ThreadLocal valueAlors, quelle est la relation entre ThreadLocal et Thread ? Comment les deux peuvent-ils lire la valeur ? Vous trouverez ci-dessous une brève analyse basée sur le code source.La relation entre ThreadLocal et Thread
Premier coup d'oeil à la méthode set de 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); }
<🎜. >3. Combinez la valeur avec l'objet ThreadLocal. Formez vous-même un objet Entry et enregistrez-le dans le tableau de type Entry de
ThreadLoalMap.
Jetons un coup d'œil à la méthode get de 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(); }
1. Obtenir l'objet Thread actuel
2. Récupérer l'objet ThreadLocalMap de l'objet Thread actuel
3. Récupérer l'objet Entry associé à ThreadLocal à partir de ThreadLocalMap, en utilisant spécifiquement ThreadLocal comme objet clé.
4. Obtenez l'attribut value de l'entrée à l'étape 3 et renvoyez-le.
En observant les méthodes get et set dans leur ensemble, nous pouvons tirer les conclusions suivantes : L'objet ThreadLocal appelle la méthode set pour ajouter de la valeur au ThreadLocalMap de l'objet Thread ; valeur du ThreadLocalMap de l’objet Thread. Le cœur est de manipuler l'objet ThreadLocalMap de l'objet Thread pour lire et écrire la valeur. Le principe est aussi simple que cela.
Alors, quelle est la relation entre les différents objets ThreadLocal situés dans différents threads et enregistrant des valeurs dans d'autres threads ? Cela peut être clairement décrit à travers l'image suivante :
Exemples d'utilisation de ThreadLocalNous savons que sous Android, il n'y a qu'A Objet Looper, alors comment faire ? C'est ThreadLocal qui joue un rôle. Jetez un œil à la méthode de préparation du Looper :
//定义一个静态的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)); }
Vous pouvez le savoir en observant la méthode de préparation. Tout d'abord, utilisez la méthode get de sThreadLocal pour déterminer si le thread actuel a déjà un Looper. object. Si tel est le cas, lancez une exception. Si le thread actuel n'a pas défini d'objet Looper, appelez la méthode set de ThreadLocal pour initialiser un objet Looper et transférez-le au thread actuel :
sThreadLocal.set(new Looper(quitAllowed));
Cela garantit que un thread n'a qu'un seul objet Looper.
Jusqu'à présent, le principe de ThreadLocal a été essentiellement analysé. Quant à la manière de configurer et d'obtenir en interne, le blogueur n'a pas fait d'analyse trop détaillée car il n'est pas nécessaire de comprendre les raisons de fonctionnement et les scénarios d'utilisation de ThreadLocal. . C'est ça.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!