SyncLock, instruction
Acquiert un verrou exclusif pour un bloc d'instruction avant d'exécuter le bloc.
SyncLock lockobject
[ block ]
End SyncLock
Composants
lockobject
Requis.Expression qui prend la valeur d'une référence d'objet.block
Optionnel.Bloc d'instructions qui doivent être exécutées lorsque le verrou est acquis.End SyncLock
Met fin à un bloc SyncLock.
Notes
L'instruction SyncLock garantit que plusieurs threads n'exécutent pas le bloc d'instructions en même temps.SyncLock empêche chaque thread d'entrer dans le bloc jusqu'à ce qu'aucun autre thread ne l'exécute.
L'utilisation la plus courante de SyncLock est d'empêcher la mise à jour des données par plusieurs threads simultanément.Si les instructions qui manipulent les données doivent être exécutées sans interruption, mettez-les dans un bloc SyncLock.
Un bloc d'instruction protégé par un verrou exclusif est parfois appelé une section critique.
Règles
Branchement.Vous ne pouvez pas vous brancher dans un bloc SyncLock de l'extérieur du bloc.
Valeur de l'objet lock.La valeur de lockobject ne peut pas être Nothing.Vous devez créer l'objet lock avant de l'utiliser dans une instruction SyncLock.
Vous ne pouvez pas modifier la valeur de lockobject en exécutant un bloc SyncLock.Le mécanisme exige que l'objet lock reste inchangé.
Vous ne pouvez pas utiliser l'opérateur d' attendez dans un bloc d' SyncLock .
Comportement
Mécanisme.Lorsqu'un thread atteint l'instruction SyncLock, il évalue l'expression lockobject et interrompt l'exécution jusqu'à ce qu'il acquière un verrou exclusif sur l'objet retourné par l'expression.Lorsqu'un autre thread atteint l'instruction SyncLock, il n'acquiert pas de verrou jusqu'à ce que le premier thread exécute l'instruction End SyncLock.
Données protégées.Si lockobject est une variable Shared, le verrou exclusif empêche un tread d'exécuter le bloc SyncLock dans toute instance de la classe pendant qu'un autre l'exécute.Cela protège des données qui sont partagées par toutes les instances.
Si lockobject est une variable d'instance (non Shared), le verrou empêche un thread qui s'exécute dans l'instance en cours d'exécuter le bloc SyncLock en même temps qu'un autre thread dans la même instance.Cela protège des données gérées par l'instance.
Acquisition et libération.Un bloc SyncLock se comporte comme une construction Try...Finally dans laquelle le bloc Try acquiert un verrou exclusif sur lockobject et le bloc Finally le libère.C'est pourquoi le bloc SyncLock garantit la libération du verrou, peu importe comment vous quittez le bloc.Cela est vrai même dans le cas d'une exception non gérée.
Appels du Framework.Le bloc SyncLock acquiert et libère le verrou exclusif en appelant les méthodes Enter et Exit de la classe Monitor dans l'espace de noms System.Threading.
Méthodes de programmation
L'expression lockobject doit toujours prendre la valeur d'un objet qui appartient exclusivement à votre classe.Vous devez déclarer une variable objet Private pour protéger des données qui appartiennent à l'instance en cours ou une variable objet Private Shared pour protéger des données communes à toutes les instances.
Vous ne devez pas utiliser le mot clé Me pour fournir un objet lock aux données de l'instance.Si un code externe à votre classe comporte une référence à une instance de votre classe, il pourrait utiliser cette référence comme un objet lock pour un bloc SyncLock complètement différent du vôtre, protégeant des données différentes.De cette manière, votre classe et l'autre classe pourraient s'empêcher l'une l'autre d'exécuter leurs blocs SyncLock non liés.Un verrouillage de ce type sur une chaîne peut poser problème puisque tout autre code du processus utilisant la même chaîne partagera le même verrouillage.
De même, vous ne devez pas utiliser la méthode Me.GetType pour fournir un objet lock aux données partagées.Cela est dû au fait que GetType retourne toujours le même objet Type pour un nom de classe donné.Le code externe pourrait appeler GetType de votre classe et obtenir le même objet lock que vous utilisez.Les deux classes s'empêcheraient l'une l'autre d'exécuter à leurs blocs SyncLock.
Exemples
Description
L'exemple suivant affiche une classe qui gère une liste ordinaire de messages.Il stocke les messages dans un tableau et le dernier élément utilisé de ce tableau dans une variable.La procédure addAnotherMessage incrémente le dernier élément et stocke le nouveau message.Ces deux opérations sont protégées par les instructions SyncLock et End SyncLock, car une fois que le dernier élément a été incrémenté, le nouveau message doit être stocké avant que tout autre thread puisse incrémenter encore le dernier élément.
Si la classe simpleMessageList partage une liste de messages entre toutes ses instances, les variables messagesList et messagesLast sont déclarées comme Shared.Dans ce cas, les messagesLock de variables doivent être également Shared, afin qu'il y ait un objet lock seul utilisé par chaque instance.
Code
Class simpleMessageList
Public messagesList() As String = New String(50) {}
Public messagesLast As Integer = -1
Private messagesLock As New Object
Public Sub addAnotherMessage(ByVal newMessage As String)
SyncLock messagesLock
messagesLast += 1
If messagesLast < messagesList.Length Then
messagesList(messagesLast) = newMessage
End If
End SyncLock
End Sub
End Class
Description
L'exemple suivant utilise des threads et SyncLock :Tant que l'instruction SyncLock est présente, le bloc d'instructions est une section critique et balance ne devient jamais un nombre négatif.Vous pouvez commenter les instructions SyncLock et End SyncLock pour observer l'effet de la mise à l'écart du mot clé SyncLock.
Code
Imports System.Threading
Module Module1
Class Account
Dim thisLock As New Object
Dim balance As Integer
Dim r As New Random()
Public Sub New(ByVal initial As Integer)
balance = initial
End Sub
Public Function Withdraw(ByVal amount As Integer) As Integer
' This condition will never be true unless the SyncLock statement
' is commented out:
If balance < 0 Then
Throw New Exception("Negative Balance")
End If
' Comment out the SyncLock and End SyncLock lines to see
' the effect of leaving out the SyncLock keyword.
SyncLock thisLock
If balance >= amount Then
Console.WriteLine("Balance before Withdrawal : " & balance)
Console.WriteLine("Amount to Withdraw : -" & amount)
balance = balance - amount
Console.WriteLine("Balance after Withdrawal : " & balance)
Return amount
Else
' Transaction rejected.
Return 0
End If
End SyncLock
End Function
Public Sub DoTransactions()
For i As Integer = 0 To 99
Withdraw(r.Next(1, 100))
Next
End Sub
End Class
Sub Main()
Dim threads(10) As Thread
Dim acc As New Account(1000)
For i As Integer = 0 To 9
Dim t As New Thread(New ThreadStart(AddressOf acc.DoTransactions))
threads(i) = t
Next
For i As Integer = 0 To 9
threads(i).Start()
Next
End Sub
End Module
Voir aussi
Référence
Synchronisation des threads (C# et Visual Basic)