Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A blokk végrehajtása előtt kizárólagos zárolást szerez be egy utasításblokkhoz.
Szemantika
SyncLock lockobject
[ block ]
End SyncLock
Részek
lockobject
Szükséges. Objektumhivatkozásként kiértékelt kifejezés.
block
Opcionális. A zárolás beszerzésekor végrehajtandó utasítások blokkja.
End SyncLock
Leállítja a blokkot SyncLock .
Megjegyzések
Az SyncLock utasítás biztosítja, hogy több szál ne hajtsa végre egyszerre az utasításblokkot.
SyncLock megakadályozza, hogy az egyes szálak mindaddig belépnek a blokkba, amíg más szál nem hajtja végre.
A leggyakoribb használat SyncLock az adatok több szál általi egyidejű frissítésének védelme. Ha az adatokat kezelő utasításoknak megszakítás nélkül kell befejeződniük, helyezze őket egy SyncLock blokkba.
A kizárólagos zárolással védett utasításblokkokat kritikus szakasznak is nevezik.
Szabályok
Elágazó. A blokkon kívülről nem ágazhat be blokkba
SyncLock.Objektumérték zárolása. Az érték
lockobjectnem lehetNothing. A zárolási objektumot az utasításbanSyncLockvaló használat előtt létre kell hoznia.A blokk végrehajtása közben nem módosíthatja
lockobjectaz értékeketSyncLock. A mechanizmus megköveteli, hogy a zárolási objektum változatlan maradjon.Blokkban nem használhatja a Várakozás operátort
SyncLock.
Magatartás
Mechanizmus. Amikor egy szál eléri az
SyncLockutasítást, kiértékeli a kifejezést, és felfüggeszti alockobjectvégrehajtást, amíg nem szerez kizárólagos zárolást a kifejezés által visszaadott objektumon. Amikor egy másik szál eléri azSyncLockutasítást, nem szerez be zárolást, amíg az első szál nem hajtja végre az utasítástEnd SyncLock.Védett adatok. Ha
lockobjectváltozóShared, a kizárólagos zárolás megakadályozza, hogy az osztály bármely példányában egy szál végrehajtsa aSyncLockblokkot, miközben bármely más szál végrehajtja azt. Ez védi az összes példány között megosztott adatokat.Ha
lockobjectegy példányváltozó (nemShared), a zárolás megakadályozza, hogy az aktuális példányban futó szál a blokkot ugyanabban aSyncLockpéldányban egy másik szállal egyidejűleg hajtsa végre. Ez védi az egyes példányok által kezelt adatokat.Beszerzés és kiadás. A
SyncLockblokkok úgy viselkednek, mint egyTry...Finallyolyan szerkezet, amelyben aTryblokk kizárólagos zárolástlockobjectszerez be, és aFinallyblokk felszabadítja azt. Emiatt aSyncLockblokk garantálja a zárolás feloldását, függetlenül attól, hogy hogyan lép ki a blokkból. Ez még kezeletlen kivétel esetén is igaz.Keretrendszerhívások. A
SyncLockblokk a névtérben lévő osztály és metódusok meghívásávalEnterszerzi be ésExitoldja fel aMonitorkizárólagos zárolást System.Threading .
Programozási eljárások
A lockobject kifejezésnek mindig olyan objektumra kell kiértékelnie, amely kizárólag az osztályhoz tartozik. Deklarálnia kell egy objektumváltozót Private az aktuális példányhoz tartozó adatok védelméhez, vagy egy objektumváltozót Private Shared az összes példányra jellemző adatok védelméhez.
A kulcsszóval nem Me adhat meg zárolási objektumot a példányadatokhoz. Ha az osztályon kívüli kód hivatkozással rendelkezik az osztály egy példányára, akkor ezt a hivatkozást használhatja zárolási objektumként egy SyncLock olyan blokkhoz, amely teljesen eltér az Önétől, és védi a különböző adatokat. Ily módon az osztály és a másik osztály megakadályozhatja egymást a nem kapcsolódó SyncLock blokkok végrehajtásában. Hasonlóképpen a sztring zárolása is problémás lehet, mivel az ugyanazon sztringet használó folyamat bármely más kódja ugyanazt a zárolást fogja használni.
A metódust nem használhatja Me.GetType a megosztott adatok zárolási objektumának megadására. Ennek az az oka, hogy GetType mindig ugyanazt Type az objektumot adja vissza egy adott osztálynévhez. A külső kód meghívhatja GetType az osztályt, és beszerezheti a használt zárolási objektumot. Ez azt eredményezné, hogy a két osztály blokkolja egymást a blokkjaikból SyncLock .
Példák
Leírás
Az alábbi példa egy olyan osztályt mutat be, amely egyszerű üzenetlistát tart fenn. Egy tömbben lévő üzeneteket és a tömb utolsó használt elemét tárolja egy változóban. Az addAnotherMessage eljárás növeli az utolsó elemet, és tárolja az új üzenetet. Ezt a két műveletet az és az SyncLockEnd SyncLock utasítások védik, mivel az utolsó elem növekménye után az új üzenetet tárolni kell, mielőtt bármely más szál újra növektetheti az utolsó elemet.
Ha az simpleMessageList osztály az összes példánya között megosztott egy üzenetlistát, a változók messagesList és messagesLast a deklarálva Sharedlesznek. Ebben az esetben a változónak messagesLock is meg kell lennie Shared, hogy minden példány egyetlen zárolási objektumot használjon.
Kód
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
Leírás
Az alábbi példa szálakat és SyncLock. Amíg az SyncLock utasítás jelen van, az utasításblokk kritikus szakasz, és balance soha nem lesz negatív szám. Megjegyzéseket fűzhet a SyncLock kulcsszavakhoz, így End SyncLock láthatja a kulcsszó kihagyásának SyncLock hatását.
Kód
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