Quelles sont les causes des problèmes de sécurité multithread de Java SE ?
阿神2017-06-12 09:26:22
0
5
958
Peut-être que le code dans l'image a une faible probabilité de nombres négatifs, mais si vous ajoutez Thread.sleep(10); après l'instruction if, vous pouvez voir la sortie de nombres négatifs
Je ne sais pas ce que vous demandez. Il est normal que plusieurs threads lisent une ressource en même temps et aient des problèmes de désynchronisation. En effet, un thread peut obtenir une valeur tandis qu'un autre thread en écrit une. valeur, ce qui entraînera des problèmes de synchronisation.
Il existe de nombreuses solutions. La plus stupide est d'ajouter directement la synchronisation au bloc de code et de verrouiller l'intégralité du code. La meilleure est d'utiliser des classes thread-safe, comme AtomIntegercelle-ci, pour assurer la synchronisation. de recherche sur le multi-threading, vous pouvez même simplement ajouter très peu de verrous qui font le travail.
L'ordre d'appel des threads n'est pas garanti d'être dans l'ordre La raison fondamentale réside dans la commutation entre les threads lorsque la JVM coordonne les ressources.
Il n'y a pas de synchronisation de num. Il n'y a aucune garantie qu'une fois que le thread actuel a modifié la valeur de num, les autres threads peuvent la voir immédiatement. Prenons le code du sujet comme exemple. Supposons que num=1 soit exécuté jusqu'à la fin et que trois threads exécutent le jugement if en même temps, et que tous peuvent juger de la réussite, alors un nombre négatif peut apparaître.
1. Visibilité de la mémoire 2. Atomicité des modifications
Puisque num est une variable statique, elle sera stockée dans le tas. Lorsque la méthode run() est exécutée, une copie sera copiée dans la pile pour le stockage. Lorsque plusieurs threads la modifient, la même copie peut être obtenue en même temps. en même temps, mais en raison de l'ordre d'exécution, un thread modifie et écrit la variable. Bien que le nombre dans le tas ait changé, les autres threads ne le savent pas et continueront à modifier cette copie. Ensuite, la modification est écrite dans le tas, ce qui écrasera les modifications du thread précédent, entraînant une incohérence d'état. Et si la sécurité des fils pouvait être assurée ? Assurez-vous ensuite que la visibilité de la modification de la zone du tas est garantie avant de modifier num, et prenez-en une copie avant de la modifier (même si elle a déjà été prise auparavant). Cela peut être garanti par le mot-clé volatile.
Atomicité, puisque l'exécution réelle de num-- est constituée de deux opérations, il y aura un problème d'ordre d'exécution. Même si j'ai mentionné plus tôt que volatile est utilisé pour assurer la visibilité. Cependant, il y aura toujours des situations où les modifications seront écrasées par d'autres threads, mais le risque est moindre. Pour garantir l'atomicité, vous pouvez utiliser le mot-clé synchronisé, le mécanisme de verrouillage et la boîte à outils de concurrence JDK, etc. Pour cette situation, la solution la plus simple est
Je ne sais pas ce que vous demandez. Il est normal que plusieurs threads lisent une ressource en même temps et aient des problèmes de désynchronisation. En effet, un thread peut obtenir une valeur tandis qu'un autre thread en écrit une. valeur, ce qui entraînera des problèmes de synchronisation.
Il existe de nombreuses solutions. La plus stupide est d'ajouter directement la synchronisation au bloc de code et de verrouiller l'intégralité du code. La meilleure est d'utiliser des classes thread-safe, comme
AtomInteger
celle-ci, pour assurer la synchronisation. de recherche sur le multi-threading, vous pouvez même simplement ajouter très peu de verrous qui font le travail.L'ordre d'appel des threads n'est pas garanti d'être dans l'ordre La raison fondamentale réside dans la commutation entre les threads lorsque la JVM coordonne les ressources.
La raison essentielle est que le CPU réorganise les instructions afin d'améliorer l'efficacité
Il n'y a pas de synchronisation de num. Il n'y a aucune garantie qu'une fois que le thread actuel a modifié la valeur de num, les autres threads peuvent la voir immédiatement.
Prenons le code du sujet comme exemple. Supposons que num=1 soit exécuté jusqu'à la fin et que trois threads exécutent le jugement if en même temps, et que tous peuvent juger de la réussite, alors un nombre négatif peut apparaître.
1. Visibilité de la mémoire
2. Atomicité des modifications
Puisque num est une variable statique, elle sera stockée dans le tas. Lorsque la méthode run() est exécutée, une copie sera copiée dans la pile pour le stockage. Lorsque plusieurs threads la modifient, la même copie peut être obtenue en même temps. en même temps, mais en raison de l'ordre d'exécution, un thread modifie et écrit la variable. Bien que le nombre dans le tas ait changé, les autres threads ne le savent pas et continueront à modifier cette copie. Ensuite, la modification est écrite dans le tas, ce qui écrasera les modifications du thread précédent, entraînant une incohérence d'état.
Et si la sécurité des fils pouvait être assurée ? Assurez-vous ensuite que la visibilité de la modification de la zone du tas est garantie avant de modifier num, et prenez-en une copie avant de la modifier (même si elle a déjà été prise auparavant). Cela peut être garanti par le mot-clé volatile.
Atomicité, puisque l'exécution réelle de num-- est constituée de deux opérations, il y aura un problème d'ordre d'exécution. Même si j'ai mentionné plus tôt que volatile est utilisé pour assurer la visibilité. Cependant, il y aura toujours des situations où les modifications seront écrasées par d'autres threads, mais le risque est moindre. Pour garantir l'atomicité, vous pouvez utiliser le mot-clé synchronisé, le mécanisme de verrouillage et la boîte à outils de concurrence JDK, etc. Pour cette situation, la solution la plus simple est