Bagikan melalui


Pernyataan SyncLock

Memperoleh kunci eksklusif untuk blok pernyataan sebelum menjalankan blok.

Sintaksis

SyncLock lockobject  
    [ block ]  
End SyncLock  

Bagian

lockobject
Dibutuhkan. Ekspresi yang mengevaluasi ke referensi objek.

block
Fakultatif. Blok pernyataan yang akan dijalankan saat kunci diperoleh.

End SyncLock
Mengakhiri blok SyncLock .

Komentar

Pernyataan ini SyncLock memastikan bahwa beberapa utas tidak menjalankan blok pernyataan secara bersamaan. SyncLock mencegah setiap utas memasuki blok hingga tidak ada utas lain yang mengeksekusinya.

Penggunaan SyncLock yang paling umum adalah melindungi data agar tidak diperbarui oleh lebih dari satu utas secara bersamaan. Jika pernyataan yang memanipulasi data harus selesai tanpa gangguan, letakkan di dalam SyncLock blok.

Blok pernyataan yang dilindungi oleh kunci eksklusif terkadang disebut bagian penting.

Aturan

  • Bercabang. Anda tidak dapat bercabang SyncLock ke blok dari luar blok.

  • Kunci Nilai Objek. Nilai tidak lockobject boleh Nothing. Anda harus membuat objek kunci sebelum menggunakannya dalam SyncLock pernyataan.

    Anda tidak dapat mengubah nilai lockobject saat menjalankan SyncLock blok. Mekanisme mengharuskan objek kunci tetap tidak berubah.

  • Anda tidak dapat menggunakan operator Tunggu di SyncLock blok.

Perilaku

  • Mekanisme. Ketika utas mencapai SyncLock pernyataan, utas lockobject mengevaluasi ekspresi dan menangguhkan eksekusi hingga memperoleh kunci eksklusif pada objek yang dikembalikan oleh ekspresi. Ketika utas lain mencapai pernyataan, utas SyncLock tersebut tidak memperoleh kunci sampai utas End SyncLock pertama menjalankan pernyataan.

  • Data yang Dilindungi. Jika lockobject adalah Shared variabel, kunci eksklusif mencegah utas dalam instans kelas apa pun dari SyncLock menjalankan blok sementara utas lain mengeksekusinya. Ini melindungi data yang dibagikan di antara semua instans.

    Jika lockobject adalah variabel instans (bukan Shared), kunci mencegah utas yang berjalan dalam instans saat ini agar tidak mengeksekusi SyncLock blok secara bersamaan dengan utas lain dalam instans yang sama. Ini melindungi data yang dikelola oleh instans individual.

  • Akuisisi dan Rilis. Blok SyncLock bersifat seperti Try...Finally konstruksi di mana Try blok memperoleh kunci lockobject eksklusif dan Finally blok melepaskannya. Karena itu, SyncLock blok menjamin pelepasan kunci, tidak peduli bagaimana Anda keluar dari blok. Ini berlaku bahkan dalam kasus pengecualian yang tidak tertangani.

  • Panggilan Kerangka Kerja. Blok memperoleh SyncLock dan melepaskan kunci eksklusif dengan memanggil Enter metode Monitor dan Exit kelas di System.Threading namespace layanan.

Praktik Pemrograman

lockobject Ekspresi harus selalu mengevaluasi ke objek yang dimiliki secara eksklusif untuk kelas Anda. Anda harus mendeklarasikan Private variabel objek untuk melindungi data milik instans saat ini, atau Private Shared variabel objek untuk melindungi data yang umum untuk semua instans.

Anda tidak boleh menggunakan Me kata kunci untuk menyediakan objek kunci untuk data instans. Jika kode eksternal ke kelas Anda memiliki referensi ke instans kelas Anda, kode tersebut dapat menggunakan referensi tersebut sebagai objek kunci untuk blok yang SyncLock sama sekali berbeda dari milik Anda, melindungi data yang berbeda. Dengan cara ini, kelas Anda dan kelas lainnya dapat memblokir satu sama lain agar tidak mengeksekusi blok yang tidak terkait SyncLock . Penguncian serupa pada string dapat bermasalah karena kode lain dalam proses menggunakan string yang sama akan berbagi kunci yang sama.

Anda juga tidak boleh menggunakan Me.GetType metode untuk menyediakan objek kunci untuk data bersama. Ini karena GetType selalu mengembalikan objek yang sama Type untuk nama kelas tertentu. Kode eksternal dapat memanggil GetType kelas Anda dan mendapatkan objek kunci yang sama dengan yang Anda gunakan. Ini akan mengakibatkan dua kelas memblokir satu sama lain dari blok mereka SyncLock .

Contoh

Deskripsi

Contoh berikut menunjukkan kelas yang mempertahankan daftar pesan sederhana. Ini menyimpan pesan dalam array dan elemen terakhir yang digunakan dari array tersebut dalam variabel. Prosedur menaikkan addAnotherMessage elemen terakhir dan menyimpan pesan baru. Kedua operasi tersebut SyncLock dilindungi oleh pernyataan dan End SyncLock , karena setelah elemen terakhir bertambah, pesan baru harus disimpan sebelum utas lain dapat menaikkan elemen terakhir lagi.

simpleMessageList Jika kelas berbagi satu daftar pesan di antara semua instansnya, variabel messagesList dan messagesLast akan dinyatakan sebagai Shared. Dalam hal ini, variabel messagesLock juga harus Shared, sehingga akan ada satu objek kunci yang digunakan oleh setiap instans.

Kode

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

Deskripsi

Contoh berikut menggunakan utas dan SyncLock. Selama SyncLock pernyataan ada, blok pernyataan adalah bagian penting dan balance tidak pernah menjadi angka negatif. Anda dapat mengomentari SyncLock pernyataan dan End SyncLock untuk melihat efek meninggalkan SyncLock kata kunci.

Kode

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

Komentar

Lihat juga