SyncLock Deyimi
Bloğu yürütmeden önce bir ifade bloğu için özel bir kilit elde edin.
Syntax
SyncLock lockobject
[ block ]
End SyncLock
Bölümler
lockobject
Gereklidir. Bir nesne başvurusunu değerlendiren ifade.
block
İsteğe bağlı. Kilit elde edildiğinde yürütülecek deyimler bloğu.
End SyncLock
Bir SyncLock bloğu sonlandırır.
Açıklamalar
SyncLockİfade, birden çok iş parçacığının aynı anda ekstre bloğunu yürütmemesini sağlar. SyncLock başka bir iş parçacığı yürütülene kadar her bir iş parçacığının blok girmesini engeller.
En yaygın kullanımı, SyncLock verilerin birden fazla iş parçacığı tarafından aynı anda güncelleştirilmesini sağlar. Verileri işleyen deyimlerin kesinti olmadan tamamlanmasına gitmesi gerekiyorsa, bunları bir blok içine koyun SyncLock .
Özel bir kilit tarafından korunan bir ifade bloğu bazen kritik bir bölüm olarak adlandırılır.
Kurallar
Dallanma. Bloğunun dışından bir bloğa dallandırılamıyor
SyncLock.Nesne değerini kilitle. Değeri olamaz
lockobjectNothing. Bir ifadede kullanmadan önce Lock nesnesini oluşturmanız gerekirSyncLock.lockobjectBir blok yürütülürken değerini değiştiremezsinizSyncLock. Mekanizma, kilit nesnesinin değişmeden kalmasını gerektirir.Bir blokta await işlecini kullanamazsınız
SyncLock.
Davranış
Mekanizmadır. Bir iş parçacığı ifadeye ulaştığında
SyncLock, ifadeyi değerlendirirlockobjectve ifadenin döndürdüğü nesne üzerinde dışlamalı bir kilit elde edene kadar yürütmeyi askıya alır. Başka bir iş parçacığıSyncLockifadeye ulaştığında, ilk iş parçacığı ifadeyi çalıştırana kadar bir kilit almazEnd SyncLock.Korumalı veriler.
lockobjectBirShareddeğişkense, dışlamalı kilit,SyncLockbaşka bir iş parçacığı yürütülürken, sınıfın herhangi bir örneğindeki bir iş parçacığının bloğunu yürütmesini engeller. Bu, tüm örnekler arasında paylaşılan verileri korur.lockobjectBir örnek değişkenidir (değilShared), kilit, geçerli örnekte çalışan bir iş parçacığınınSyncLockaynı anda aynı örnekteki başka bir iş parçacığı ile aynı zamanda yürütülmesini önler. Bu, bireysel örnek tarafından tutulan verileri korur.Alma ve yayınlama. Bir
SyncLockblokTry...Finally, blok üzerinde özel bir kilit elde eden bir oluşturma gibi davranırTrylockobjectveFinallyblok onu yayınlar. Bu nedenle, bloğundanSyncLockçıktığınızda, blok kilidi garanti eder. Bu, işlenmemiş bir özel durum durumunda bile geçerlidir.Çerçeve çağrıları.
SyncLockBloğu,EnterExitMonitorad alanındaki sınıfının ve yöntemlerini çağırarak dışlamalı kilidi alır ve serbest bırakır System.Threading .
Programlama uygulamaları
lockobjectİfade her zaman yalnızca kendi sınıfınıza ait olan bir nesne olarak değerlendirilir. PrivateGeçerli örneğe ait verileri korumak için bir nesne değişkeni veya Private Shared tüm örneklerde ortak olan verileri korumak için bir nesne değişkeni bildirmeniz gerekir.
MeÖrnek verileri için bir kilit nesnesi sağlamak üzere anahtar sözcüğünü kullanmamalısınız. Sınıfınıza dış kod, sınıfınızın bir örneğine başvuru içeriyorsa, bu başvuruyu SyncLock kendi sizinkinden tamamen farklı, farklı verileri koruyan bir blok için bir kilit nesnesi olarak kullanabilir. Bu şekilde, sınıfınız ve diğer sınıf, birbirini ilgisiz blokları yürütmelerini engelleyebilir SyncLock . Aynı dizeyi kullanan işlemdeki diğer kodlar aynı kilidi paylaştığından, bir dizedeki aynı şekilde kilitleme sorunlu olabilir.
Ayrıca, Me.GetType paylaşılan veriler için bir kilit nesnesi sağlamak üzere metodunu kullanmamalısınız. Bunun nedeni, GetType her zaman Type belirli bir sınıf adı için aynı nesneyi döndürmektedir. Dış kod GetType , sınıfınıza çağrı verebilir ve kullanmakta olduğunuz kilit nesnesini alabilir. Bu, iki sınıfın bloklarından birbirini engellemesine neden olur SyncLock .
Örnekler
Açıklama
Aşağıdaki örnek, bir ileti listesini tutan bir sınıfı gösterir. Bir dizideki iletileri ve bu dizinin son kullanılan öğesini bir değişkende tutar. addAnotherMessageYordam, son öğeyi artırır ve yeni iletiyi depolar. Bu iki işlem ve deyimleri tarafından korunur SyncLock End SyncLock , çünkü son öğe artdıktan sonra yeni ileti, diğer herhangi bir iş parçacığının son öğeyi yeniden artırılabilmesi için önce depolanmalıdır.
Sınıf, simpleMessageList tüm örnekleri arasında bir ileti listesi paylaşmışsa, değişkenleri messagesList ve messagesLast olarak olarak bildirilenler Shared . Bu durumda, değişken messagesLock de olmalıdır Shared , böylece her örnek tarafından kullanılan tek bir kilit nesnesi olur.
Kod
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
Aşağıdaki örnek, ve iş parçacıklarını kullanır SyncLock . Deyimin bulunduğu sürece SyncLock , ifade bloğu kritik bir bölümdür ve balance hiçbir zaman negatif bir sayı değildir. SyncLock End SyncLock Anahtar sözcüğünü bırakma etkisini görmek için ve deyimlerini açıklama ekleyebilirsiniz SyncLock .
Kod
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