web-dev-qa-db-fra.com

La version C # du mot clé synchronisé de Java?

C # a-t-il sa propre version du mot-clé Java "synchronisé"?

C'est à dire. dans Java, vous pouvez spécifier une fonction, un objet ou un bloc de code, comme suit:

public synchronized void doImportantStuff() {
   // dangerous code goes here.
}

ou

public void doImportantStuff() {
   // trivial stuff

   synchronized(someLock) {
      // dangerous code goes here.
   }
}
293
Soraz

Premièrement - la plupart des classes n'auront jamais besoin d'être thread-safe. Utilisez YAGNI : appliquez la sécurité du fil uniquement lorsque vous savez que vous allez réellement l'utiliser (et le tester).

Pour les choses au niveau de la méthode, il y a [MethodImpl]:

[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}

Ceci peut également être utilisé sur des accesseurs (propriétés et événements):

private int i;
public int SomeProperty
{
    [MethodImpl(MethodImplOptions.Synchronized)]
    get { return i; }
    [MethodImpl(MethodImplOptions.Synchronized)]
    set { i = value; }
}

Notez que les événements de type champ sont synchronisés par défaut, tandis que les propriétés implémentées automatiquement ne le sont pas :

public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized

Personnellement, je n'aime pas l'implémentation de MethodImpl car elle verrouille this ou typeof(Foo) - ce qui va à l'encontre des meilleures pratiques. L'option préférée est d'utiliser vos propres verrous:

private readonly object syncLock = new object();
public void SomeMethod() {
    lock(syncLock) { /* code */ }
}

Notez que pour les événements de type champ, l'implémentation de verrouillage dépend du compilateur; dans les anciens compilateurs Microsoft, il s'agit d'une lock(this)/lock(Type) - cependant, dans les compilateurs plus récents, il utilise Interlocked mises à jour - donc thread-safe sans les parties malveillantes.

Cela permet une utilisation plus granulaire et l'utilisation de Monitor.Wait/Monitor.Pulse etc. pour communiquer entre les threads.

A lié entrée de blog (plus tard revisité ).

444
Marc Gravell
static object Lock = new object();

lock (Lock) 
{
// do stuff
}
54
Jan Gressmann

C # a-t-il sa propre version du mot-clé Java "synchronisé"?

Non. En C #, vous explicitement lock ressources sur lesquelles vous souhaitez travailler de manière synchrone sur des threads asynchrones. lock ouvre un bloc; cela ne fonctionne pas au niveau de la méthode.

Cependant, le mécanisme sous-jacent est similaire car lock fonctionne en appelant Monitor.Enter (et ensuite _Monitor.Exit_) lors de l'exécution. Java fonctionne de la même manière, selon le documentation de Sun .

39
Konrad Rudolph

Notez que, avec les chemins complets, la ligne: [MethodImpl(MethodImplOptions.Synchronized)] devrait ressembler à

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]

7
Traubenfuchs

Vous pouvez utiliser l'instruction lock à la place. Je pense que cela ne peut que remplacer la deuxième version. De plus, rappelez-vous que synchronized et lock doivent fonctionner sur un objet.

5
James