Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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
SyncLockke blok dari luar blok.Kunci Nilai Objek. Nilai tidak
lockobjectbolehNothing. Anda harus membuat objek kunci sebelum menggunakannya dalamSyncLockpernyataan.Anda tidak dapat mengubah nilai
lockobjectsaat menjalankanSyncLockblok. Mekanisme mengharuskan objek kunci tetap tidak berubah.Anda tidak dapat menggunakan operator Tunggu di
SyncLockblok.
Perilaku
Mekanisme. Ketika utas mencapai
SyncLockpernyataan, utaslockobjectmengevaluasi ekspresi dan menangguhkan eksekusi hingga memperoleh kunci eksklusif pada objek yang dikembalikan oleh ekspresi. Ketika utas lain mencapai pernyataan, utasSyncLocktersebut tidak memperoleh kunci sampai utasEnd SyncLockpertama menjalankan pernyataan.Data yang Dilindungi. Jika
lockobjectadalahSharedvariabel, kunci eksklusif mencegah utas dalam instans kelas apa pun dariSyncLockmenjalankan blok sementara utas lain mengeksekusinya. Ini melindungi data yang dibagikan di antara semua instans.Jika
lockobjectadalah variabel instans (bukanShared), kunci mencegah utas yang berjalan dalam instans saat ini agar tidak mengeksekusiSyncLockblok secara bersamaan dengan utas lain dalam instans yang sama. Ini melindungi data yang dikelola oleh instans individual.Akuisisi dan Rilis. Blok
SyncLockbersifat sepertiTry...Finallykonstruksi di manaTryblok memperoleh kuncilockobjecteksklusif danFinallyblok melepaskannya. Karena itu,SyncLockblok menjamin pelepasan kunci, tidak peduli bagaimana Anda keluar dari blok. Ini berlaku bahkan dalam kasus pengecualian yang tidak tertangani.Panggilan Kerangka Kerja. Blok memperoleh
SyncLockdan melepaskan kunci eksklusif dengan memanggilEntermetodeMonitordanExitkelas 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