SyncLock wyciągu
Uzyskuje blokadę wyłączności dla bloku instrukcji przed wykonaniem bloku.
SyncLock lockobject
[ block ]
End SyncLock
Części
lockobject
Wymagane.Wyrażenie, którego wynikiem jest odwołanie do obiektu.block
Opcjonalne.Blok instrukcji, które są po blokady.End SyncLock
Kończy SyncLock bloku.
Uwagi
SyncLock Instrukcji gwarantuje, że wiele wątków nie wykonanie instrukcji bloku w tym samym czasie.SyncLockKażdy wątek uniemożliwia wprowadzanie bloku aż żaden inny wątek jest on wykonywany.
Najczęściej z SyncLock jest ochrona danych przed aktualizowany przez więcej niż jeden wątek jednocześnie.Jeśli w instrukcji, które manipulowania danymi, należy przejść do zakończenia bez przerwy, umieść je wewnątrz SyncLock bloku.
Chronione przez blokadę wyłączności blok instrukcji jest czasami nazywany sekcji krytycznej.
Zasady
Rozgałęzianie.Nie Rozgałęzienie do SyncLock zablokować z poza blokiem.
Zablokuj wartości obiektu.Wartość lockobject nie może być Nothing.Należy utworzyć obiekt Zablokuj przed użyciem go w SyncLock instrukcji.
Nie można zmienić wartości lockobject podczas wykonywania SyncLock bloku.Mechanizm wymaga, aby zablokować obiektu pozostają niezmienione.
Nie można użyć Await operatora w SyncLock bloku.
Zachowanie
Mechanizm.Gdy wątek osiągnie SyncLock wynikiem instrukcji, lockobject wyrażenie i zawiesza wykonywanie aż kupuje blokadę wyłączności na obiekt zwrócony przez wyrażenie.Gdy inny wątek osiągnie SyncLock instrukcji, to nie nabywa blokady aż pierwszy wątek wykonuje End SyncLock instrukcji.
Chronionych danych.Jeśli lockobject jest Shared zmiennej, blokada wyłączności uniemożliwia wątek w dowolnej instancji klasy wykonywanie SyncLock blokowanie, podczas gdy inny wątek jest on wykonywany.Chroni to dane wspólne wszystkich instancji.
Jeśli lockobject jest zmienną instancji (nie Shared), Blokada zapobiega wątek działający w bieżącej instancji wykonywanie SyncLock bloku jednocześnie inny wątek w tym samym wystąpieniu.Chroni to dane obsługiwane przez poszczególnych instancji.
Nabycie i wydania.A SyncLock bloku zachowuje się jak Try...Finally konstrukcji, w którym Try bloku przejmuje wyłączną blokadę na lockobject i Finally zwolni blok.W związku z tym SyncLock bloku gwarancje release blokady, niezależnie od tego, jak zakończyć bloku.Jest to nawet w przypadku nieobsłużonego wyjątku.
Ramy wywołań.SyncLock Bloku nabywa i zwalnia blokadę wyłączności przez wywołanie Enter i Exit metody Monitor klasy w System.Threading obszaru nazw.
Programowanie praktyk
lockobject Wyrażenia powinna zawsze być obiekt, który należy wyłącznie do swojej klasy.Należy zadeklarować Private zmienną obiektu, aby chronić dane należące do bieżącego wystąpienia lub Private Shared zmienną obiektu, aby chronić dane wspólne dla wszystkich wystąpień.
Nie należy używać Me słowo kluczowe, aby zapewnić blokady, na przykład obiekt danych.Jeśli kod zewnętrzny względem klasy zawiera odwołanie do instancji klasy, można użyć tego odwołania jako obiekt blokady dla SyncLock bloku całkowicie różna od zamierzonej, ochrona różnych danych.W ten sposób klasy i inne klasy może blokować wzajemnie wykonywanie ich niepowiązanych SyncLock bloków.Podobnie blokowania na ciąg może być problematyczne, ponieważ inny kod procesu przy użyciu samego ciągu będzie udostępniać blokadę.
Ponadto nie należy korzystać z Me.GetType metodę w celu zapewnienia zablokować obiektu dla udostępnianych danych.Wynika to z GetType zawsze zwraca to samo Type nazwę danej klasy obiektu.Kod zewnętrzny może wywołać GetType w klasie i uzyskania są przy użyciu tego samego obiektu blokady.Spowodowałoby to dwie klasy blokowania innych z ich SyncLock bloków.
Przykłady
Opis
Poniższy przykład pokazuje klasy, która utrzymuje proste listy wiadomości.Przechowuje wiadomości w tablicy i ostatni używany element tablicy w zmiennej.addAnotherMessage Procedury zwiększa ostatni element i zapisuje nowe wiadomości.Te dwie operacje są chronione przez SyncLock i End SyncLock instrukcji, ponieważ po ostatnim elementem została zwiększona, nowe wiadomości muszą być przechowywane przed inny wątek może zwiększać ostatni element ponownie.
Jeśli simpleMessageList klasy udostępnione jednej listy wiadomości między wszystkie jego wystąpienia, zmienne messagesList i messagesLast mogłyby być zadeklarowany jako Shared.W przypadku zmiennej messagesLock może być również Shared, dzięki czemu będzie obiekt pojedynczej blokady używane przez każde wystąpienie.
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
Opis
Poniższy przykład używa wątków i SyncLock.Tak długo, jak SyncLock deklaracji, instrukcji bloku jest sekcji krytycznej i balance nigdy nie staje się liczbę ujemną.Można wykomentować SyncLock i End SyncLock instrukcji, aby zobaczyć efekt pomijając SyncLock słowa kluczowego.
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
Zobacz też
Informacje
Wątek synchronizacji (C# i Visual Basic)