SyncLock ステートメントSyncLock Statement

ブロックを実行する前にステートメント ブロックの排他ロックを取得します。Acquires an exclusive lock for a statement block before executing the block.

構文Syntax

SyncLock lockobject  
    [ block ]  
End SyncLock  

指定項目Parts

lockobject
必須。Required. オブジェクト参照に評価される式。Expression that evaluates to an object reference.

block
任意。Optional. ロックが取得されるときに実行されるステートメントのブロックです。Block of statements that are to execute when the lock is acquired.

End SyncLock
終了、SyncLockブロックします。Terminates a SyncLock block.

RemarksRemarks

SyncLockステートメントが複数のスレッドが同時にステートメント ブロックを実行しないことを保証します。The SyncLock statement ensures that multiple threads do not execute the statement block at the same time. SyncLock 各スレッドが実行している他のスレッドがなくなるまで、ブロックを入力するを防ぎます。SyncLock prevents each thread from entering the block until no other thread is executing it.

最も一般的な用途SyncLockから複数のスレッドによって同時に更新されたデータを保護することです。The most common use of SyncLock is to protect data from being updated by more than one thread simultaneously. 場合は、データを操作するステートメントは、中断することがなく完了するまで移動する必要があります、配置内でそれらをSyncLockブロックします。If the statements that manipulate the data must go to completion without interruption, put them inside a SyncLock block.

排他ロックによって保護されているステートメント ブロックが呼び出される場合があります、クリティカル セクションします。A statement block protected by an exclusive lock is sometimes called a critical section.

ルールRules

  • 分岐します。Branching. 分岐することはできません、SyncLockブロックの外側からブロックされます。You cannot branch into a SyncLock block from outside the block.

  • オブジェクトの値をロックします。Lock Object Value. lockobjectすることはできませんNothingします。The value of lockobject cannot be Nothing. 使用する前に、ロック オブジェクトを作成する必要があります、SyncLockステートメント。You must create the lock object before you use it in a SyncLock statement.

    値を変更することはできませんlockobjectの実行中に、SyncLockブロックします。You cannot change the value of lockobject while executing a SyncLock block. メカニズムは、ロック オブジェクトが変わらないことが必要です。The mechanism requires that the lock object remain unchanged.

  • 使用することはできません、 Awaitで演算子をSyncLockブロックします。You can't use the Await operator in a SyncLock block.

動作Behavior

  • メカニズムです。Mechanism. スレッドが達したとき、SyncLockステートメントでは、評価、lockobject式と式によって返されるオブジェクトの排他ロックを取得するまで実行を中断します。When a thread reaches the SyncLock statement, it evaluates the lockobject expression and suspends execution until it acquires an exclusive lock on the object returned by the expression. 別のスレッドが達したとき、SyncLockステートメントでは、これはロックを取得、最初のスレッドが実行されるまで、End SyncLockステートメント。When another thread reaches the SyncLock statement, it does not acquire a lock until the first thread executes the End SyncLock statement.

  • 保護されたデータ。Protected Data. 場合lockobjectは、Shared変数、排他ロック クラスの任意のインスタンス内のスレッドが実行されないように、SyncLock他のスレッドが実行中にブロックします。If lockobject is a Shared variable, the exclusive lock prevents a thread in any instance of the class from executing the SyncLock block while any other thread is executing it. これは、すべてのインスタンス間で共有されるデータを保護します。This protects data that is shared among all the instances.

    場合lockobjectインスタンス変数は、(いないShared)、ロックにより、スレッドの実行を現在のインスタンスで実行できなくなります、SyncLock同じインスタンス内の別のスレッドと同時にブロックします。If lockobject is an instance variable (not Shared), the lock prevents a thread running in the current instance from executing the SyncLock block at the same time as another thread in the same instance. これは、個々 のインスタンスで保持されるデータを保護します。This protects data maintained by the individual instance.

  • 取得と解放します。Acquisition and Release. ASyncLockブロックのように動作をTry...Finallyを構築、Tryブロックで排他ロックを取得するlockobjectFinallyブロックでは、それを解放します。A SyncLock block behaves like a Try...Finally construction in which the Try block acquires an exclusive lock on lockobject and the Finally block releases it. このため、SyncLockブロックがブロックを終了する方法に関係なく、ロックの解放を保証します。Because of this, the SyncLock block guarantees release of the lock, no matter how you exit the block. これはハンドルされない例外の場合にも当てはまります。This is true even in the case of an unhandled exception.

  • フレームワーク。Framework Calls. SyncLockブロックを取得し、呼び出すことによって、排他ロックを解放、EnterExitのメソッド、Monitorクラス、System.Threading名前空間。The SyncLock block acquires and releases the exclusive lock by calling the Enter and Exit methods of the Monitor class in the System.Threading namespace.

プログラミング手法Programming Practices

lockobject式は常をクラスにのみ属しているオブジェクトを評価する必要があります。The lockobject expression should always evaluate to an object that belongs exclusively to your class. 宣言する必要があります、Privateオブジェクト変数を現在のインスタンスに属するデータを保護またはPrivate Sharedオブジェクト変数をすべてのインスタンスに共通のデータを保護します。You should declare a Private object variable to protect data belonging to the current instance, or a Private Shared object variable to protect data common to all instances.

使用しないようにする、Meロックを提供するキーワードはオブジェクトのインスタンス データ。You should not use the Me keyword to provide a lock object for instance data. ロック オブジェクトとしてその参照を使用できます、クラスの外部のコードに、クラスのインスタンスへの参照がある場合、SyncLockブロックから、まったく異なる別のデータを保護します。If code external to your class has a reference to an instance of your class, it could use that reference as a lock object for a SyncLock block completely different from yours, protecting different data. この方法で、クラスとその他のクラスでした互いにブロックの実行が関連付けられていないSyncLockブロックします。In this way, your class and the other class could block each other from executing their unrelated SyncLock blocks. 同様に、文字列をロックも問題が、同じ文字列を使用して、プロセスの他のコードが同じロックを共有します。Similarly locking on a string can be problematic since any other code in the process using the same string will share the same lock.

使用しないようにする、Me.GetTypeのロック オブジェクトを提供するメソッドは、データを共有します。You should also not use the Me.GetType method to provide a lock object for shared data. これは、ためGetType常に、同じを返しますTypeオブジェクトの特定のクラス名。This is because GetType always returns the same Type object for a given class name. 外部コードを呼び出すことがGetTypeクラスを使用している同じロック オブジェクトを取得します。External code could call GetType on your class and obtain the same lock object you are using. 結果から互いをブロックしている 2 つのクラスになり、SyncLockブロックします。This would result in the two classes blocking each other from their SyncLock blocks.

使用例Examples

説明Description

次の例では、メッセージの単純なリストを保持するクラスを示します。The following example shows a class that maintains a simple list of messages. 配列内のメッセージを保持し、最後は、変数にその配列の要素を使用します。It holds the messages in an array and the last used element of that array in a variable. addAnotherMessageプロシージャが最後の要素をインクリメントし、新しいメッセージを格納します。The addAnotherMessage procedure increments the last element and stores the new message. これら 2 つの操作がによって保護されている、SyncLockEnd SyncLockステートメント、他のスレッドはその最後の要素をインクリメントする前に、新しいメッセージを格納する必要があるしたら、最後の要素がインクリメントされていたためです。Those two operations are protected by the SyncLock and End SyncLock statements, because once the last element has been incremented, the new message must be stored before any other thread can increment the last element again.

場合、simpleMessageListクラスは、そのすべてのインスタンス、変数間のメッセージの 1 つのリストを共有messagesListmessagesLast宣言Sharedします。If the simpleMessageList class shared one list of messages among all its instances, the variables messagesList and messagesLast would be declared as Shared. この場合は、変数messagesLock必要もありますShared、すべてのインスタンスによって使用される 1 つのロック オブジェクトがあるようにします。In this case, the variable messagesLock should also be Shared, so that there would be a single lock object used by every 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

次のコードの例では、スレッドとSyncLockします。The following example uses threads and SyncLock. 限り、SyncLockステートメントが存在する、ステートメント ブロックがクリティカル セクションとbalance決して、負の数。As long as the SyncLock statement is present, the statement block is a critical section and balance never becomes a negative number. コメント アウトすることができます、SyncLockEnd SyncLock隠れますの効果を確認するステートメント、SyncLockキーワード。You can comment out the SyncLock and End SyncLock statements to see the effect of leaving out the SyncLock keyword.

コード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

コメントComments

関連項目See Also

System.Threading
Monitor
スレッドの同期Thread Synchronization
スレッド化Threading