Maison > Java > javaDidacticiel > Comment utiliser la classe java.lang.ThreadLocal

Comment utiliser la classe java.lang.ThreadLocal

PHPz
Libérer: 2023-05-05 20:43:13
avant
765 Les gens l'ont consulté

1. Aperçu

Qu’est-ce que ThreadLocal ? En fait, ThreadLocal n'est pas une version d'implémentation locale d'un thread. Ce n'est pas un Thread, mais une variable locale de thread (variable locale de thread). Il serait peut-être plus approprié de le nommer ThreadLocalVar. La fonction réelle des variables locales de thread (ThreadLocal) est très simple. Il s'agit de fournir une copie de la valeur de la variable pour chaque thread qui utilise la variable. Il s'agit d'un mécanisme de liaison de thread spécial en Java qui permet à chaque thread de modifier indépendamment le vôtre. copier sans entrer en conflit avec les copies des autres threads.

Du point de vue d'un thread, chaque thread conserve une référence implicite à sa copie d'une variable locale de thread tant que le thread est actif et que l'instance ThreadLocal est accessible après la disparition du thread, toutes les copies de son instance locale de thread seront des déchets ; collection (sauf s’il existe d’autres références à ces copies).

Les données accessibles via ThreadLocal sont toujours liées au thread actuel. En d'autres termes, la JVM lie un espace d'accès à une instance locale privée à chaque thread en cours d'exécution, fournissant ainsi une solution aux problèmes d'accès simultanés qui surviennent souvent dans les environnements multithread. .

Comment ThreadLocal conserve-t-il une copie des variables pour chaque thread ? En fait, l'idée d'implémentation est très simple. Il existe une Map dans la classe ThreadLocal, qui est utilisée pour stocker une copie des variables de chaque thread.

En résumé, pour le problème du partage de ressources multi-thread, le mécanisme de synchronisation adopte la méthode « d'échange de temps contre de l'espace », tandis que ThreadLocal adopte la méthode « d'échange d'espace contre du temps ». Le premier fournit uniquement une copie de la variable pour que différents threads puissent faire la queue pour y accéder, tandis que le second fournit une copie de la variable pour chaque thread, de sorte qu'il soit possible d'y accéder en même temps sans s'affecter mutuellement.

2. Description de l'API

SujetLocal()

Créez une variable locale de thread.

J'obtiens()

Renvoie la valeur dans la copie du thread actuel de cette variable locale du thread, qui est créée et initialisée si c'est la première fois que le thread appelle cette méthode.

protected T initialValue()

Renvoie la valeur initiale du thread actuel pour cette variable locale du thread. Cette méthode est appelée au plus une fois par accès au thread pour obtenir chaque variable locale du thread, c'est-à-dire lorsque le thread accède pour la première fois à la variable à l'aide de la méthode get(). Si le thread appelle la méthode set(T) avant la méthode get, la méthode initialValue ne sera plus appelée dans le thread.

Si cette implémentation renvoie simplement null ; si le programmeur souhaite initialiser les variables locales du thread à une valeur autre que null, le programmeur doit sous-classer ThreadLocal et remplacer cette méthode. En règle générale, des classes internes anonymes seront utilisées. Une implémentation typique de initialValue appellera un constructeur approprié et renverra l'objet nouvellement construit.

void supprimer()

Supprime la valeur de cette variable locale du thread. Cela peut aider à réduire les besoins de stockage pour les variables locales des threads. Si cette variable locale du thread est à nouveau accédée, elle aura sa valeur initiale par défaut.

ensemble vide (valeur T)

Définit la valeur dans la copie du thread actuel de cette variable locale du thread sur la valeur spécifiée. De nombreuses applications ne nécessitent pas cette fonctionnalité et s'appuient uniquement sur la méthode initialValue() pour définir la valeur des variables locales du thread.

Dans les programmes, la méthode initialValue est généralement remplacée pour donner une valeur initiale spécifique.

3. Exemples typiques

1. Classe d'outils Session d'Hiberante HibernateUtil

Cette classe est la classe HibernateUtil dans la documentation officielle d'Hibernate et est utilisée pour la gestion des sessions.

classe publique HibernateUtil {

journal de journal statique privé = LogFactory.getLog(HibernateUtil.class);

sessionFactory finale statique privée sessionFactory ; //Définir SessionFactory

statique {

essayez {

//Créez SessionFactory

via le fichier de configuration par défaut hibernate.cfg.xml sessionFactory = new Configuration().configure().buildSessionFactory();

} attraper (Ex jetable) {

log.error("L'initialisation de SessionFactory a échoué !", ex);

lancer une nouvelle ExceptionInInitializerError(ex);

}

}

//Créer une session de variable locale de thread pour enregistrer la session d'Hibernate

session ThreadLocal finale statique publique = new ThreadLocal();

/**

* Obtenez la session dans le fil de discussion actuel

* @session de retour

* @throws HibernateException

*/

La session statique publique currentSession() lance HibernateException {

Session s = (Session) session.get();

// Si la Session n'est pas encore ouverte, ouvrez une nouvelle Session

si (s == nul) {

s = sessionFactory.openSession();

session.set(s); //Enregistrez la session nouvellement ouverte dans les variables locales du thread

}

retour s;

}

public static void closeSession() lance HibernateException {

//Obtenir les variables locales du thread et les convertir en type de session

Session s = (Session) session.get();

session.set(null);

si (s != nul)

s.close();

}

}

Dans cette classe, puisque la méthode initialValue() de ThreadLocal n'est pas remplacée, la session variable locale du thread est créée pour la première fois et sa valeur initiale est nulle. Lorsque currentSession() est appelée pour la première fois, la méthode get(). de la variable locale du thread est également null . Par conséquent, la session est jugée. Si elle est nulle, une nouvelle session est ouverte et enregistrée dans la variable locale du thread session. Il s'agit également de l'objet créé par "public static final ThreadLocal session = new ThreadLocal(). " La raison pour laquelle la session peut être forcée à devenir un objet Session Hibernate.

2. Un autre exemple

Créez un Bean et définissez les propriétés du Bean via différents objets thread pour garantir l'indépendance de chaque objet Bean thread.

/**

* Créé par IntelliJ IDEA.

* Utilisateur : leizhimin

* Date : 2007-11-23

* Heure : 10:45:02

* 学生

*/

Étudiant de classe publique {

âge int privé = 0 ; //âge

public int getAge() {

rends cet.age;

}

public void setAge(int âge) {

this.age = âge;

}

}

/**

* Créé par IntelliJ IDEA.

* Utilisateur : leizhimin

* Date : 2007-11-23

* Heure : 10:53:33

* Programme de test sous multi-threading

*/

classe publique ThreadLocalDemo implémente Runnable {

//Créez la variable locale du fil studentLocal, que vous retrouverez plus tard pour sauvegarder l'objet Student

privé final statique ThreadLocal studentLocal = new ThreadLocal();

public static void main(String[] agrs) {

ThreadLocalDemo td = new ThreadLocalDemo();

Sujet t1 = nouveau sujet(td, "a");

Sujet t2 = nouveau sujet(td, "b");

t1.start();

t2.start();

}

public void run() {

accessStudent();

}

/**

* Exemple de méthode commerciale pour les tests

*/

public void accessStudent() {

//Obtenir le nom du fil de discussion actuel

Chaîne currentThreadName = Thread.currentThread().getName();

System.out.println(currentThreadName + " est en cours d'exécution !");

//Générer un nombre aléatoire et imprimer

Aléatoire aléatoire = nouveau Aléatoire();

int age = random.nextInt(100);

System.out.println("thread " + currentThreadName + " définir l'âge sur :" + age);

//Obtenez un objet Student et insérez l'âge aléatoire dans les propriétés de l'objet

Étudiant étudiant = getStudent();

étudiant.setAge(age);

System.out.println("thread " + currentThreadName + " l'âge de première lecture est :" + student.getAge());

essayez {

Discussion.sleep(500);

}

catch (InterruptedException ex) {

ex.printStackTrace();

}

System.out.println("thread " + currentThreadName + " l'âge de la deuxième lecture est :" + student.getAge());

}

Étudiant protégé getStudent() {

//Obtenir les variables de thread locales et les convertir en type Student

Étudiant étudiant = (Étudiant) studentLocal.get();

//Lorsque le thread exécute cette méthode pour la première fois, studentLocal.get() doit être null

si (étudiant == nul) {

//Créez un objet Student et enregistrez-le dans la variable de fil local studentLocal

étudiant = nouvel étudiant ();

étudiantLocal.set(étudiant);

}

retour étudiant;

}

}

Résultat en course :

a est en marche !

enfilez un âge défini à : 76

b est en cours d'exécution !

le fil de discussion b fixe l'âge à : 27

fil de discussion, l'âge de première lecture est : 76 

l'âge de la première lecture du fil B est : 27

fil de discussion, l'âge d'une deuxième lecture est : 76

l'âge de la deuxième lecture du fil b est : 27

On peut voir que les valeurs imprimées par les deux threads vieillissent à des moments différents sont exactement les mêmes. Ce programme utilise ThreadLocal pour obtenir une concurrence multithread tout en prenant en compte la sécurité des données.

4. Résumé

ThreadLocal est principalement utilisé pour résoudre le problème d'incohérence des données due à la concurrence dans les multi-threads. ThreadLocal fournit une copie des données accédées simultanément pour chaque thread et exécute l'entreprise en accédant à la copie. Cela consomme de la mémoire, réduit considérablement la consommation de performances causée par la synchronisation des threads et réduit également la complexité du contrôle de la concurrence des threads.

ThreadLocal ne peut pas utiliser de types atomiques, uniquement des types d'objet. L'utilisation de ThreadLocal est beaucoup plus simple que synchronisée.

ThreadLocal et Synchonized sont utilisés pour résoudre l'accès simultané multithread. Mais il existe une différence essentielle entre ThreadLocal et synchronisé. Synchronized utilise un mécanisme de verrouillage afin qu'une variable ou un bloc de code ne soit accessible que par un seul thread à la fois. ThreadLocal fournit une copie de la variable pour chaque thread, afin que chaque thread n'accède pas au même objet à un certain moment, isolant ainsi le partage de données par plusieurs threads. Synchronisé est tout le contraire. Il est utilisé pour obtenir le partage de données lors de la communication entre plusieurs threads.

Synchronized est utilisé pour le partage de données entre les threads, tandis que ThreadLocal est utilisé pour l'isolation des données entre les threads.

Bien entendu, ThreadLocal ne peut pas remplacer la synchronisation, ils traitent différents domaines problématiques. Synchronized est utilisé pour implémenter le mécanisme de synchronisation et est plus complexe que ThreadLocal.

5. Étapes générales d'utilisation de ThreadLocal

1. Dans une classe multithread (telle que la classe ThreadDemo), créez un objet ThreadLocal threadXxx pour enregistrer l'objet xxx qui doit être isolé entre les threads.

2. Dans la classe ThreadDemo, créez une méthode getXxx() pour obtenir les données auxquelles accéder de manière isolée. Jugez dans la méthode que si l'objet ThreadLocal est nul, vous devez new() un objet de type accès isolation et le forcer. à appliquer.

3. Dans la méthode run() de la classe ThreadDemo, obtenez les données à exploiter via la méthode getXxx(). Cela garantit que chaque thread correspond à un objet de données, et que cet objet est exploité à tout moment.

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!

Étiquettes associées:
source:yisu.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal