OK, c'est un peu plus compliqué que la question.
class A { static int needsToBeThreadSafe = 0; public static void M1() { needsToBeThreadSafe = RandomNumber(); } public static void M2() { print(needsToBeThreadSafe); } }
7 Réponses :
class A { static int needsToBeThreadSafe = 0; static object statObjLocker = new object(); public static void M1() { lock(statObjLocker) { needsToBeThreadSafe = RandomNumber(); } } public static void M2() { lock(statObjLocker) { print(needsToBeThreadSafe); } } }
Vous avez deux choix: les plus simples que votre code présenté est le mot clé qui étant dit, si vous voulez mieux vous assurer que sur quelle approche à prendre, c'est à vous et doit être déterminé par le code. Si tout ce dont vous avez besoin est de vous assurer qu'un assignation de membre est propagé à tous les threads et n'est pas mis en cache, le mot clé code> volatile code> est plus simple et fera le travail tout à fait. Si c'est au-delà de cela, vous voudrez peut-être aller avec le verrouillage volatile code>. Déclare
NeedstobetHreadsafe Code> comme
statique volatil int code> et qui garantira que tout fil qui fait référence à la variable obtiendra la "dernière" copie et la variable ne sera pas mise en cache dans votre code. .
m1 () code> et
m2 () code> exécuter "atomiquement" (ou au moins exclusivement l'un de l'autre) , alors vous voulez utiliser un verrouillage
code>. La syntaxe la plus propre est avec un "bloc de verrouillage", comme celui-ci: p>
code>. P> p>
Son comme vous avez besoin d'un volatile membre.
static volatile int needsToBeThreadSafe = 0;
C'était un commentaire de 2009, mais de nos jours, il est préférable d'éviter de volatiles, car il a des effets secondaires ...
Qu'est-ce que vous essayez d'essayer de poser une question sur l'attribut [ threadstatic fort>]. Si vous voulez chaque fil qui utilise la classe Pour plus d'informations, reportez-vous au Documentation MSDN pour A code> strud> pour avoir sa propre valeur distincte de
NeedstobetHreadsafe code> strong> alors vous avez juste besoin de décorer ce champ avec l'attribut [ threadstatic fort>]. p>
threadstaticattribute code>
. p>
Je suppose que tout le monde avait aussi raison, mais pour ma situation, cela fonctionne parfaitement.
D'une manière ou d'une autre, je viens de réaliser que ce qu'il est réellement après une valeur qui n'est pas partagée entre les threads. En outre, ThreadStatic est B> Safe-Safe-Safe car il n'y a même pas deux threads accéder à la même variable (même s'il semble qu'ils sont).
@paraccler: Bon travail pour répondre à la question, mais éliminer le potentiel de conflit en créant des copies locales signifie que ceci est, par définition, pas de "fil sûr". Bien que ce ne soit pas "dangereux", la sécurité du fil signifie qu'il gère correctement plusieurs threads traitant de la ressource la même i>; Je ne dirais pas que la copie de la ressource est un moyen de le faire.
I DO B> Obtenez vos points et je ne veux pas étendre inutilement la conversation, mais ma compréhension du "thread-coffre-fort" est si un morceau de code est sûr de fonctionner simultanément sous plusieurs threads. "Storage local" est une implémentation triviale de cette définition et pourrait ne pas répondre à vos besoins si vous avez réellement besoin de données partagées. Si ce dont vous avez besoin est de multiples threads d'exécution sans threads sur les pieds de chacun, et le "stockage local de thread-local" répond à vos besoins, c'est la voie à suivre. En outre, l'article Wikipedia ( en.wikipedia.org/wiki/Trhead_Safety ) semble être d'accord avec moi.
La chose ici est que cela rend une variable statique A Variable de fil-locale B>, mais qui reste un membre de l'ensemble de fil-coffre-fort :).
Vous pouvez également utiliser le ReaderWriterLockSLIM, qui est plus efficace pour plusieurs lectures et moins écrit:
static int needsToBeThreadSafe = 0; static System.Threading.ReaderWriterLockSlim rwl = new System.Threading.ReaderWriterLockSlim(); public static void M1() { try { rwl.EnterWriteLock(); needsToBeThreadSafe = RandomNumber(); } finally { rwl.ExitWriteLock(); } } public static void M2() { try { rwl.EnterReadLock(); print(needsToBeThreadSafe); } finally { rwl.ExitReadLock(); } }
Pour commencer avec je suis d'accord avec les réponses à l'aide de Il existe une approche plus minimaliste, votre code d'exemple ne montre que des déclarations simples en utilisant verrouillage () code>, c'est la manière la plus sûre.
NeedstobetHreadsafe CODE> et puisque
INT CODE> FORT> est atomique, il vous suffit d'empêcher la mise en cache par le compilateur à l'aide de volatiles: P>
class A
{
static volatile int needsToBeThreadSafe = 0;
}
C'est la réponse de 2009, mais de nos jours, il serait préférable d'utiliser dans la réponse à la réponse suggérée que volatile que volatile a des effets secondaires, qui ont tendance à créer des problèmes facilement ...
Que diriez-vous:
public static void M1() { Interlocked.Exchange( ref needsToBeThreadSafe, RandomNumber() ); } public static void M2() { print( Interlocked.Read( ref needsToBeThreadSafe ) ); }
J'adore celui-ci, c'est sûr et est super rapide, la honte qu'elle n'avait que 4 upvotes (mienne incluses) après une demi-décennie!
Vous voulez dire que vous voulez que les appels à M1 () et M2 () soient atomiques?
Qu'entendez-vous par «Séjours en sécurité du fil»?