Maison >Java >javaDidacticiel >Explication détaillée de InheritableThreadLocal dans le multithreading Java

Explication détaillée de InheritableThreadLocal dans le multithreading Java

黄舟
黄舟original
2017-10-19 10:00:462104parcourir

Cet article présente principalement en détail InheritableThreadLocal dans la programmation multi-thread Java, qui a une certaine valeur de référence. Les amis intéressés peuvent se référer à

Le rôle de InheritableThreadLocal : lorsque nous devons utiliser des sous-threads lors de l'utilisation du. valeur dans le thread parent, nous pouvons utiliser InheritableThreadLocal comme ThreadLocal.

Tout d'abord, jetons un coup d'œil au code source jdk de InheritableThreadLocal :


package java.lang;
import java.lang.ref.*;

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
  protected T childValue(T parentValue) {
    return parentValue;
  }

  ThreadLocalMap getMap(Thread t) {
    return t.inheritableThreadLocals;
  }

  void createMap(Thread t, T firstValue) {
    t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);
  }
}

Ce code est le code source complet de InheritableThreadLocal (un long a été supprimé) commentaires).

Nous pouvons d'abord voir qu'il hérite de la classe ThreadLocal, puis fournit : la méthode

protected T childValue(T parentValue){}, c'est la clé de InheritableThreadLocal Par conséquent, il fournit cette méthode pour renvoyer la valeur dans le thread parent. Si vous devez également ajouter une valeur sur le thread parent, vous pouvez remplacer la méthode childValue.


package InheritableThreadLocal;

import java.util.Date;

public class InheritableThreadLocaExt extends InheritableThreadLocal{
  protected Object initialValue() {
    return new Date().getTime();

  }
  protected Object childValue(Object parentValue) {
    return parentValue+"对继承值进行修改";

  }

}

package InheritableThreadLocal;

public class tool {
  public static InheritableThreadLocaExt t=new InheritableThreadLocaExt();

}

package InheritableThreadLocal;

public class MyThread extends Thread{

  public void run() {
      try {
        for(int i=0;i<10;i++) {
          System.out.println("在线程A中:"+tool.t.get());
        sleep(100);
        }
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }  
}

package InheritableThreadLocal;

public class test {
  public static void main(String[] args) {
    try {
      for(int i=0;i<10;i++) {
        System.out.println("主线程中值:"+tool.t.get());
        Thread.sleep(100);
      }
      Thread.sleep(5000);
      MyThread thread=new MyThread();
      thread.start();

    }catch(InterruptedException e){
      e.printStackTrace();
    }
  }
}

Sortie d'exécution :

Médiane du fil principal : 1508210392057
Médiane du fil principal : 1508210392057
Valeur médiane du fil principal : 1508210392057
Fil principal médian : 1508210392057
Fil principal médian : 1508210392057
Fil principal médian : 1508210392057
Fil principal médian : 1508210392057
Fil principal Valeur : 1508210392057
Valeur médiane du fil principal : 1508210392057
Valeur médiane du thread principal : 1508210392057
Dans le thread A : 1508210392057 Modification de la valeur héritée
Dans le thread A : 1508210392057 Modification de la valeur héritée
Dans le thread Dans A : 1508210392057 Modifie la valeur héritée
Dans le fil A : 1508210392057 Modifie la valeur héritée
Dans le fil A : 1508210392057 Modifie la valeur héritée
Dans le fil A : 1508210392057 Modifie la valeur héritée Modification
Dans le fil A : 1508210392057 Modification de la valeur héritée
Dans fil A : 1508210392057 Modification de la valeur héritée
Dans le fil A : 1508210392057 Modification de la valeur héritée
Dans le fil A : 1508210392057 Modifier la valeur héritée

Vous avez une question, pourquoi le le thread enfant obtient-il les données du thread parent ?

Nous pouvons voir que InheritableThreadLocal réécrit la méthode getMap et la méthode createMap Lorsque nous avons parlé de ThreadLocal dans la section précédente, nous savions que la valeur de ThreadLocal est stockée dans une variable appelée ThreadLocals, mais maintenant elle l'est. renvoie un InheritableThreadLocals, cette variable est exactement la même que ThreadLocals mais le nom a été modifié. Alors pourquoi puis-je toujours obtenir la valeur via la méthode threadlocal.get() dans un nouveau thread ?

En regardant la méthode childValue, on peut deviner que certaines astuces ont pu être réalisées lors de la création du thread, et que certaines valeurs ont été transmises.

Quand on ouvre le code source de la classe Thread, on peut trouver :

ThreadLocal.ThreadLocalMap HeinableThreadLocals = null; 🎜>Ainsi, lorsque nous créons un fil de discussion enfant, il a une variable InheritableThreadLocal qui est la même que ThreadLocals. En regardant plus bas :


Le point clé. est l'extrait de code suivant :

private void init(ThreadGroup g, Runnable target, String name,
           long stackSize, AccessControlContext acc,
           .
           .
           if (inheritThreadLocals && parent.inheritableThreadLocals != null)
      this.inheritableThreadLocals =
        ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);


Continuer la lecture :

if (inheritThreadLocals && parent.inheritableThreadLocals != null)
      this.inheritableThreadLocals =
        ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);



 static ThreadLocalMap createInheritedMap(ThreadLocalMap parentMap) {
    return new ThreadLocalMap(parentMap);
  }


Avec ce code, nous obtenons d'abord la valeur du thread parent (c'est-à-dire le thread en cours d'exécution), puis utilisons une boucle for pour mettre les valeurs du thread parent dans nos valeurs nouvellement créées une à une.

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn