Dans le traitement de la concurrence du fil Java, il y a beaucoup de confusion dans l'utilisation d'un mot-clé volatile. Je pense que l'utilisation de ce mot-clé peut faire en sorte que tout se passe bien lors de l'utilisation de traitement de concurrence multithread.
La langue Java prend en charge le multi-threading. Afin de résoudre le problème de la concurrence du thread, le bloc synchrone et le mécanisme de mots clés volatils sont introduits à l'intérieur de la langue.
synchronisé
Tout le monde connaît les blocs synchronisés, et ils sont implémentés via le mot-clé synchronisé. Avec les instructions synchronisées et blocs, un seul thread peut les utiliser en même temps lors de l'accès à plusieurs threads.
Méthode ou bloc de code modifié synchronisé.
volatil
Pour les variables modifiées avec volatile, le thread lira la valeur la plus modifiée de la variable chaque fois qu'il utilise la variable. Volatile est facilement utilisé à mauvais escient et utilisé pour les opérations atomiques.
Voyons un exemple ci-dessous. Nous mettons en œuvre un compteur. Chaque fois que le thread démarre, la méthode Counter Inc sera appelée pour en ajouter une au compteur.
Environnement d'exécution - Version JDK: JDK1.6.0_31, mémoire: 3G CPU: x86 2.4G
classe publique Counter {public static int count = 0; public static void Inc () {// Le retard ici est 1 milliseconde, ce qui rend le résultat évidente {thread.sleep (1);} catch (interruptedException e) {} compter ++;} public static void Main (String [] args) {// démarrer 1000 en même temps, performant i ++ Calculs, et consulte pour le résultat de la même fois, performant i ++, et consulte le réel pour (INT I ++ Calculs pour (INT i +; i <1000; i ++) {new thread (new Runnable () {@OverRidePublic void run () {compter.inc ();}}). start ();} // la valeur de chaque exécution peut être différenteRésultat en cours: compteur.Count = 995
Le résultat de l'opération réel peut être différent à chaque fois. Le résultat de la machine est: Résultat de l'exécution: compteur.Count = 995. On peut voir que dans un environnement multi-thread, le nombre ne s'attend pas à ce que le résultat soit de 1000.
Beaucoup de gens pensent qu'il s'agit d'un problème de concurrence multi-thread. Il vous suffit d'ajouter volatile avant le nombre de variables pour éviter ce problème. Ensuite, nous modifions le code pour voir si le résultat répond à nos attentes.
public class Counter {public volatile static int count = 0;public static void inc() {//The delay here is 1 millisecond, making the result obvious try {Thread.sleep(1);} catch (InterruptedException e) {}count++;}public static void main(String[] args) {//Start 1000 threads at the same time, perform i++ calculations, and see the actual result for (int i =0Résultat en cours: compteur.Count = 992
Le résultat de l'opération n'est toujours pas aussi 1000 que nous nous attendions. Analysons les raisons ci-dessous
Dans l'article de la collection Java Garbage, l'attribution de la mémoire au moment de JVM est décrite. L'une des zones de mémoire est la pile de machines virtuelles JVM, et chaque thread a une pile de threads lorsqu'il s'exécute.
La pile de threads enregistre les informations de valeur de la variable pendant l'exécution du thread. Lorsqu'un thread accède à la valeur d'un certain objet, trouvez d'abord la valeur de la variable correspondant à la mémoire du tas via la référence de l'objet, puis mettez la mémoire du tas
La valeur spécifique de la variable est chargée dans la mémoire locale du thread et une copie de la variable est créée. Après cela, le thread n'a plus de relation avec la valeur de variable de l'objet dans la mémoire du tas, mais modifie directement la valeur de la variable de copie.
À un certain moment après modification (avant que le thread ne quitte), la valeur de la copie de la variable de thread est automatiquement écrite dans la variable d'objet dans le tas. De cette façon, la valeur de l'objet dans le tas changera. L'image suivante
lire et charger des variables de copie de la mémoire principale à la mémoire de travail actuelle
Utiliser et affecter le code d'exécution pour modifier la valeur de variable partagée
Stockez et rédigez un contenu lié à la mémoire principale avec des données de mémoire de travail
où l'utilisation et l'attribution peuvent apparaître plusieurs fois
Cependant, ces opérations ne sont pas atomiques, c'est-à-dire après la charge de lecture, si la variable de comptage de mémoire principale est modifiée, la valeur de la mémoire de travail du thread ne provoquera pas de modifications correspondantes depuis son chargement, de sorte que le résultat calculé sera différent de l'attendu.
Pour les variables modifiées par volatile, la machine virtuelle JVM garantit que la valeur chargée de la mémoire principale à la mémoire de travail du thread est la dernière
Par exemple, si le thread 1 et le thread 2 effectuent des opérations de lecture et de chargement, et constatez que la valeur du nombre dans la mémoire principale est de 5, alors la dernière valeur sera chargée
Une fois le nombre de tas modifié dans le thread 1, il sera écrit dans la mémoire principale et la variable de comptage dans la mémoire principale deviendra 6.
Étant donné que Thread 2 a déjà effectué l'opération de lecture et de charge, la valeur variable du nombre de mémoire principal sera également mise à jour à 6 après l'opération.
Cela provoque la concurrence après que deux threads soient modifiés avec le mot clé volatil dans le temps.
Ce qui précède est la signification du mot-clé volatil dans Java qui vous est 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!