Pire (ne fait pas travailler)
Changer le modificateur d'accès de l' counter
de public volatile
Comme d'autres personnes l'ont mentionné, ce sur son propre n'est en fait pas du tout en sécurité. Le point de volatile
, c'est que plusieurs threads s'exécutant sur plusieurs CPU peut et va mettre en cache des données et re-instructions de commande.
Si c'est pas volatile
, et le PROCESSEUR UN incrémente d'une valeur, puis UC B peut ne pas voir que la valeur incrémentée jusqu'à ce que quelque temps plus tard, ce qui peut causer des problèmes.
Si c'est volatile
, ce s'assure juste les 2 CPU voir les mêmes données en même temps. Cela ne les empêche pas du tout de l'entrelacement de leurs lectures et les opérations d'écriture qui est le problème que vous essayez d'éviter.
Deuxième Meilleur:
lock(this.locker) this.counter++;
C'est sécuritaire de le faire (à condition que vous n'oubliez pas de lock
partout d'autre que vous d'accéder this.counter
). Il empêche les autres threads de s'exécuter tout autre code qui est gardé par locker
.
L'utilisation de verrous aussi, évite les multi-processeurs, la réorganisation des problèmes comme ci-dessus, ce qui est excellent.
Le problème est, le verrouillage est lente, et si vous ré-utiliser l' locker
dans un autre lieu qui n'est pas vraiment lié alors vous pouvez vous retrouver bloquer vos autres threads pour aucune raison.
Meilleur
Interlocked.Increment(ref this.counter);
Ce qui est sûr, c'est l'efficacité de la lecture, de l'incrément, et d'écrire en "one hit" qui ne peut pas être interrompu. De ce fait, il ne sera pas affecter n'importe quel autre code et vous n'avez pas besoin de vous souvenir de verrouillage de l'extérieur. Il est également très rapide (comme MSDN dit, sur les modernes CPU c'est souvent littéralement un seul PROCESSEUR de l'instruction).
Je ne suis pas entièrement sûr cependant si il se retrouve autour d'autres CPU est la réorganisation des choses, ou si vous avez besoin de combiner volatile avec l'incrément.
Note de bas de page: Ce volatile est réellement bon pour.
En tant que volatile
n'empêche pas ce genre de multithreading questions, quel est-il? Un bon exemple est à dire que vous avez 2 fils, l'un qui écrit toujours dans une variable (disons queueLength
), et celui qui lit toujours de la même variable.
Si queueLength
n'est pas volatile, Un thread peut écrire 5 fois, mais le fil B peut voir ces écritures comme étant en retard (ou même potentiellement dans le mauvais ordre).
Une solution serait de verrouillage, mais vous pouvez aussi, dans cette situation, l'utilisation volatile. Cela permettrait de s'assurer que le fil B verrez toujours les plus up-to-date de chose qu'Un thread a écrit. Notez cependant que cette logique seulement fonctionne si vous avez des écrivains qui n'ont jamais lu, et les lecteurs qui n'ont jamais écrire, et si la chose que vous avez écrit est une valeur atomique. Dès que vous faites une seule lecture-modification-écriture, vous devez aller à Contrefil des opérations ou de l'utilisation d'un Verrou.