블록을 실행하기 전에 문 블록에 대한 배타적 잠금을 획득합니다.
문법
SyncLock lockobject
[ block ]
End SyncLock
부분
lockobject
필수 사항입니다. 개체 참조로 계산되는 식입니다.
block
선택 사항입니다. 잠금을 획득할 때 실행할 문 블록입니다.
End SyncLock
블록을 종료합니다 SyncLock .
비고
이 문은 SyncLock 여러 스레드가 문 블록을 동시에 실행하지 않도록 합니다.
SyncLock 는 다른 스레드가 실행되지 않을 때까지 각 스레드가 블록에 들어가지 않도록 방지합니다.
가장 일반적인 용도 SyncLock 는 둘 이상의 스레드에서 동시에 업데이트되지 않도록 데이터를 보호하는 것입니다. 데이터를 조작하는 문이 중단 없이 완료되어야 하는 경우 블록 안에 SyncLock 넣습니다.
단독 잠금으로 보호되는 문 블록을 중요한 섹션이라고도 합니다.
규칙
분기. 블록 외부에서 블록으로
SyncLock분기할 수 없습니다.Lock 개체 값입니다. 값은 을(를
lockobject) 사용할Nothing수 없습니다. 문에서 잠금 개체를 사용하려면 먼저 잠금 개체를SyncLock만들어야 합니다.블록을 실행하는
SyncLock동안의lockobject값은 변경할 수 없습니다. 메커니즘을 사용하려면 잠금 개체가 변경되지 않은 상태로 유지되어야 합니다.블록에서는 Await 연산자를
SyncLock사용할 수 없습니다.
행동
기구. 스레드가 문에
SyncLock도달하면 식에서lockobject반환된 개체에 대한 배타적 잠금을 획득할 때까지 식을 평가하고 실행을 일시 중단합니다. 다른 스레드가 문에SyncLock도달하면 첫 번째 스레드가 문을 실행할 때까지 잠금을End SyncLock획득하지 않습니다.보호된 데이터입니다. 변수인
Shared경우lockobject배타적 잠금은 클래스 인스턴스의 스레드가 다른 스레드가 블록을 실행하는 동안 블록을 실행SyncLock하지 못하게 합니다. 이렇게 하면 모든 인스턴스 간에 공유되는 데이터가 보호됩니다.인스턴스 변수가 아닌
Shared경우lockobject잠금은 현재 인스턴스에서 실행 중인 스레드가 동일한 인스턴스의 다른 스레드와 동시에 블록을 실행하는SyncLock것을 방지합니다. 이렇게 하면 개별 인스턴스에서 유지 관리하는 데이터가 보호됩니다.취득 및 릴리스. 블록은
SyncLock블록이 배타적 잠금lockobject을 획득하고 블록이Finally해제하는 생성Try처럼Try...Finally동작합니다. 이 때문에 블록은SyncLock블록을 종료하는 방법에 관계없이 잠금 해제를 보장합니다. 처리되지 않은 예외의 경우에도 마찬가지입니다.프레임워크 호출. 블록은
SyncLock네임스페이스에서 클래스의 메서드를 호출Enter하여 배타적 잠금을MonitorSystem.Threading 획득하고Exit해제합니다.
프로그래밍 사례
식은 lockobject 항상 클래스에만 속하는 개체로 평가되어야 합니다. 현재 인스턴스에 Private 속하는 데이터를 보호하기 위해 개체 변수를 선언하거나 모든 인스턴스에 공통된 Private Shared 데이터를 보호하기 위해 개체 변수를 선언해야 합니다.
키워드를 Me 사용하여 인스턴스 데이터에 대한 잠금 개체를 제공해서는 안 됩니다. 클래스 외부의 코드에 클래스 인스턴스에 대한 참조가 있는 경우 해당 참조를 사용자와 완전히 다른 블록의 SyncLock 잠금 개체로 사용하여 다른 데이터를 보호할 수 있습니다. 이러한 방식으로 클래스와 다른 클래스는 서로 관련 없는 SyncLock 블록을 실행하지 못하도록 차단할 수 있습니다. 마찬가지로 동일한 문자열을 사용하는 프로세스의 다른 코드가 동일한 잠금을 공유하기 때문에 문자열을 잠그는 것이 문제가 될 수 있습니다.
또한 공유 데이터에 대한 잠금 개체를 제공하기 위해 이 메서드를 사용하면 Me.GetType 안 됩니다. 지정된 클래스 이름에 대해 항상 동일한 Type 개체를 반환하기 때문 GetType 입니다. 외부 코드는 클래스를 호출 GetType 하고 사용 중인 것과 동일한 잠금 개체를 가져올 수 있습니다. 이로 인해 두 클래스가 블록에서 SyncLock 서로 차단됩니다.
예시
설명
다음 예제에서는 메시지의 간단한 목록을 유지 관리 하는 클래스를 보여 줍니다. 배열의 메시지와 해당 배열의 마지막으로 사용된 요소를 변수에 보관합니다. 이 프로시저는 addAnotherMessage 마지막 요소를 증가시키고 새 메시지를 저장합니다. 마지막 요소가 증가하면 다른 스레드가 마지막 요소를 다시 증가하기 전에 새 메시지를 저장해야 하므로 이러한 두 작업은 and End SyncLock 문으로 보호 SyncLock 됩니다.
클래스가 messagesLock 도 Shared있어야 합니다.
코드
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
설명
다음 예제에서는 스레드 및 SyncLock. 문이 있는 한 SyncLock 문 블록은 중요한 섹션이며 balance 음수가 되지 않습니다. 및 End SyncLock 문을 주석으로 SyncLock 처리하여 키워드를 제외 SyncLock 하는 효과를 확인할 수 있습니다.
코드
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
코멘트
참고하십시오
.NET