Comment utiliser la classe java.lang.ThreadLocal
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!

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
Échangez les visages dans n'importe quelle vidéo sans effort grâce à notre outil d'échange de visage AI entièrement gratuit !

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide du nombre parfait en Java. Nous discutons ici de la définition, comment vérifier le nombre parfait en Java ?, des exemples d'implémentation de code.

Guide de Weka en Java. Nous discutons ici de l'introduction, de la façon d'utiliser Weka Java, du type de plate-forme et des avantages avec des exemples.

Guide du nombre de Smith en Java. Nous discutons ici de la définition, comment vérifier le numéro Smith en Java ? exemple avec implémentation de code.

Dans cet article, nous avons conservé les questions d'entretien Java Spring les plus posées avec leurs réponses détaillées. Pour que vous puissiez réussir l'interview.

Java 8 présente l'API Stream, fournissant un moyen puissant et expressif de traiter les collections de données. Cependant, une question courante lors de l'utilisation du flux est: comment se casser ou revenir d'une opération FOREAK? Les boucles traditionnelles permettent une interruption ou un retour précoce, mais la méthode Foreach de Stream ne prend pas directement en charge cette méthode. Cet article expliquera les raisons et explorera des méthodes alternatives pour la mise en œuvre de terminaison prématurée dans les systèmes de traitement de flux. Lire plus approfondie: Améliorations de l'API Java Stream Comprendre le flux Forach La méthode foreach est une opération terminale qui effectue une opération sur chaque élément du flux. Son intention de conception est

Guide de TimeStamp to Date en Java. Ici, nous discutons également de l'introduction et de la façon de convertir l'horodatage en date en Java avec des exemples.

Les capsules sont des figures géométriques tridimensionnelles, composées d'un cylindre et d'un hémisphère aux deux extrémités. Le volume de la capsule peut être calculé en ajoutant le volume du cylindre et le volume de l'hémisphère aux deux extrémités. Ce tutoriel discutera de la façon de calculer le volume d'une capsule donnée en Java en utilisant différentes méthodes. Formule de volume de capsule La formule du volume de la capsule est la suivante: Volume de capsule = volume cylindrique volume de deux hémisphères volume dans, R: Le rayon de l'hémisphère. H: La hauteur du cylindre (à l'exclusion de l'hémisphère). Exemple 1 entrer Rayon = 5 unités Hauteur = 10 unités Sortir Volume = 1570,8 unités cubes expliquer Calculer le volume à l'aide de la formule: Volume = π × r2 × h (4

Java est un langage de programmation populaire qui peut être appris aussi bien par les développeurs débutants que par les développeurs expérimentés. Ce didacticiel commence par les concepts de base et progresse vers des sujets avancés. Après avoir installé le kit de développement Java, vous pouvez vous entraîner à la programmation en créant un simple programme « Hello, World ! ». Une fois que vous avez compris le code, utilisez l'invite de commande pour compiler et exécuter le programme, et « Hello, World ! » s'affichera sur la console. L'apprentissage de Java commence votre parcours de programmation et, à mesure que votre maîtrise s'approfondit, vous pouvez créer des applications plus complexes.
