De nombreux amis ont peut-être entendu parler du mot-clé volatile et peuvent l'avoir utilisé. Avant Java 5, c'était un mot-clé controversé, car l'utiliser dans des programmes a souvent abouti à des résultats inattendus. Ce n'est qu'après que Java 5 a fait le mot clé volatil qui a retrouvé sa vitalité.
La fonction du mot clé volatil est de rendre tous les threads du système de système visibles par les variables modifiées par le mot clé, et peut interdire la mémoire de travail du thread à partir de variables mises en cache modifiées par le volatil.
Scénarios d'utilisation volatils 2:
1. Visibilité: Java fournit des mots clés volatils pour assurer la visibilité.
Lorsqu'une variable partagée est modifiée par volatile, elle garantit que la valeur modifiée sera mise à jour immédiatement dans la mémoire principale, et lorsque d'autres threads doivent le lire, il lira la nouvelle valeur en mémoire.
Cependant, les variables partagées ordinaires ne peuvent garantir la visibilité, car il est incertain lorsque la variable partagée normale est écrite dans la mémoire principale après sa modification. Lorsque d'autres fils le lisent, l'ancienne valeur d'origine peut toujours être dans la mémoire, donc la visibilité ne peut être garantie.
De plus, le synchronisé et le verrouillage peuvent également garantir la visibilité. Synchronisé et Lock peuvent garantir qu'un seul thread acquiert le verrou en même temps et exécute le code de synchronisation. Avant de libérer le verrouillage, la modification de la variable sera actualisée à la mémoire principale. Par conséquent, la visibilité peut être garantie.
Regardons d'abord un morceau de code. Si le thread 1 est exécuté en premier et que le thread 2 est exécuté ultérieurement:
// Thread 1boolean stop = false; while (! stop) {DoSomething ();} // Thread 2Stop = true;Ce code est un morceau de code très typique, et de nombreuses personnes peuvent utiliser cette méthode de balisage lors de l'interruption de threads. Mais en fait, ce code fonctionnera-t-il complètement correctement? Le fil sera-t-il interrompu? Pas nécessairement. Peut-être que la plupart du temps, ce code peut interrompre les threads, mais il peut également ne pas interrompre le fil (bien que cette possibilité soit très petite, une fois que cela se produira, il provoquera une boucle morte).
Expliquons pourquoi ce code peut entraîner l'interruption du thread. Comme expliqué précédemment, chaque thread a sa propre mémoire de travail pendant le fonctionnement, donc lorsque le thread 1 est en cours d'exécution, il copiera la valeur de la variable d'arrêt et la mettra dans sa propre mémoire de travail.
Ensuite, lorsque le thread 2 modifie la valeur de la variable d'arrêt, mais n'a pas eu le temps de l'écrire dans la mémoire principale, le thread 2 va faire d'autres choses, puis le thread 1 ne connaît pas les modifications du thread 2 dans la variable d'arrêt, il continuera donc à boucler.
Mais après avoir modifié avec volatile, il devient différent:
Premièrement: l'utilisation du mot clé volatil forcera immédiatement la valeur modifiée à la mémoire principale;
Deuxièmement: si vous utilisez le mot clé volatil, lorsque le thread 2 le modifie, la ligne de cache de l'arrêt de la variable de cache dans la mémoire de travail du thread 1 sera invalide (si elle est reflétée dans la couche matérielle, la ligne de cache correspondante dans le cache L1 ou L2 du CPU est invalide);
Troisièmement: Étant donné que la ligne de cache de la variable de cache s'arrête dans la mémoire de travail du thread 1 n'est pas valide, le thread 1 le lira dans la mémoire principale lorsqu'il lit à nouveau la valeur de l'arrêt de la variable.
Ensuite, lorsque le thread 2 modifie la valeur d'arrêt (bien sûr, il y a 2 opérations ici, modifiant la valeur dans la mémoire de travail du thread 2, puis en écrivant la valeur modifiée à la mémoire), la ligne de cache de l'arrêt de la variable de cache dans la mémoire de travail du thread 1 sera invalide. Lorsque le fil 1 se lit, il constate que sa ligne de cache n'est pas valide. Il attendra que l'adresse de mémoire principale correspondante de la ligne de cache soit mise à jour, puis lira la dernière valeur dans la mémoire principale correspondante.
Alors ce que le thread 1 lit est la dernière valeur correcte.
2. Assurer l'ordre
Boolean volatile initié = false; // Thread 1: context = loshContext (); initié = true; // Thread 2: While (! Inited) {sleep ()} DosomethingWithConfig (context);Assurez-vous que le contexte a été initialisé.
3. Vérification
classe Singleton {private volatile static singleton instance = null; private singleton () {} public static singleton getInstance () {if (instance == null) {synchronisé (singleton.class) {if (instance == null) instance = new Singleton ();}} return instance;}}}Ce qui précède est une explication détaillée du rôle et de l'utilisation du mot-clé volatil dans Java présenté par l'éditeur. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!