Kapan waktu yang tepat untuk menggunakan Monitor
kelas atau lock
kata kunci untuk keamanan benang di C #?
EDIT:
Sepertinya dari jawaban sejauh lock
ini yang singkat untuk serangkaian panggilan ke Monitor
kelas. Untuk apa sebenarnya panggilan kunci itu? Atau lebih eksplisit,
class LockVsMonitor
{
private readonly object LockObject = new object();
public void DoThreadSafeSomethingWithLock(Action action)
{
lock (LockObject)
{
action.Invoke();
}
}
public void DoThreadSafeSomethingWithMonitor(Action action)
{
// What goes here ?
}
}
Memperbarui
Terima kasih atas bantuan Anda: Saya telah memposting pertanyaan lain sebagai tindak lanjut dari beberapa informasi yang Anda semua berikan. Karena Anda tampaknya berpengalaman dalam bidang ini, saya telah memposting tautan: Apa yang salah dengan solusi untuk mengunci dan mengelola pengecualian yang terkunci ini?
lock
blok.Pulse
mengunci sederhana. Ini penting dalam beberapa skenario multi-threading lanjutan. Saya tidak pernah menggunakanPulse
secara langsung.lock
hanyalah pintasan untukMonitor.Enter
dengantry
+finally
danMonitor.Exit
. Gunakan pernyataan kunci kapan pun itu cukup - jika Anda membutuhkan sesuatu seperti TryEnter, Anda harus menggunakan Monitor.sumber
Pernyataan kunci setara dengan:
Monitor.Enter(object); try { // Your code here... } finally { Monitor.Exit(object); }
Namun, perlu diingat bahwa Monitor juga dapat Wait () dan Pulse () , yang sering berguna dalam situasi multithreading yang kompleks.
Memperbarui
Namun di C # 4 penerapannya berbeda:
bool lockWasTaken = false; var temp = obj; try { Monitor.Enter(temp, ref lockWasTaken); //your code } finally { if (lockWasTaken) Monitor.Exit(temp); }
Thanx ke CodeInChaos untuk komentar dan tautan
sumber
Monitor
lebih fleksibel. Kasus penggunaan favorit saya menggunakan monitor adalah ketika Anda tidak ingin menunggu giliran Anda dan lewati saja ://already executing? forget it, lets move on if(Monitor.TryEnter(_lockObject)) { //do stuff; Monitor.Exit(_lockObject); }
sumber
Seperti yang dikatakan orang lain,
lock
"setara" denganMonitor.Enter(object); try { // Your code here... } finally { Monitor.Exit(object); }
Tapi hanya karena ingin tahu,
lock
akan menyimpan referensi pertama yang Anda berikan padanya dan tidak akan dibuang jika Anda mengubahnya. Saya tahu tidak disarankan untuk mengubah objek yang terkunci dan Anda tidak ingin melakukannya.Tetapi sekali lagi, untuk sains, ini berfungsi dengan baik:
var lockObject = ""; var tasks = new List<Task>(); for (var i = 0; i < 10; i++) tasks.Add(Task.Run(() => { Thread.Sleep(250); lock (lockObject) { lockObject += "x"; } })); Task.WaitAll(tasks.ToArray());
... Dan ini tidak:
var lockObject = ""; var tasks = new List<Task>(); for (var i = 0; i < 10; i++) tasks.Add(Task.Run(() => { Thread.Sleep(250); Monitor.Enter(lockObject); try { lockObject += "x"; } finally { Monitor.Exit(lockObject); } })); Task.WaitAll(tasks.ToArray());
Kesalahan:
Ini karena
Monitor.Exit(lockObject);
akan bertindak ataslockObject
yang telah berubah karenastrings
tidak dapat diubah, lalu Anda memanggilnya dari blok kode yang tidak tersinkronisasi .. tetapi bagaimanapun juga. Ini hanya fakta yang menyenangkan.sumber
object temp = lockObject; Monitor.Enter(temp); <...locked code...> Monitor.Exit(temp);
Keduanya adalah hal yang sama. kunci adalah kata kunci yang tajam dan gunakan kelas Monitor.
http://msdn.microsoft.com/en-us/library/ms173179(v=vs.80).aspx
sumber
Kunci dan perilaku dasar monitor (masuk + keluar) kurang lebih sama, tetapi monitor memiliki lebih banyak opsi yang memungkinkan Anda lebih banyak kemungkinan sinkronisasi.
Kuncinya adalah jalan pintas, dan ini adalah opsi untuk penggunaan dasar.
Jika Anda membutuhkan lebih banyak kontrol, monitor adalah pilihan yang lebih baik. Anda dapat menggunakan Wait, TryEnter dan Pulse, untuk penggunaan tingkat lanjut (seperti penghalang, semaphore, dan sebagainya).
sumber
Kata kunci Lock Lock memastikan bahwa satu utas mengeksekusi sepotong kode pada satu waktu.
kunci (lockObject)
{ // Body }
Kata kunci kunci menandai blok pernyataan sebagai bagian penting dengan mendapatkan kunci saling-pengecualian untuk objek tertentu, menjalankan pernyataan dan kemudian melepaskan kunci
Jika utas lain mencoba memasukkan kode terkunci, utas akan menunggu, memblokir, hingga objek dilepaskan.
Monitor Monitor adalah kelas statis dan termasuk dalam namespace System.Threading.
Ini memberikan kunci eksklusif pada objek sehingga hanya satu utas yang dapat masuk ke bagian kritis pada titik waktu tertentu.
Perbedaan antara Monitor dan Lock in C #
Kunci adalah jalan pintas untuk Monitor. Masuk dengan mencoba dan akhirnya. Gagang kunci mencoba dan akhirnya memblokir secara internal Lock = Monitor + coba akhirnya.
Jika Anda ingin lebih kontrol untuk menerapkan solusi multithreading canggih menggunakan
TryEnter()
Wait()
,Pulse()
danPulseAll()
metode, maka kelas monitor adalah pilihan Anda.C #
Monitor.wait()
: Sebuah utas menunggu utas lain untuk memberi tahu.Monitor.pulse()
: Sebuah utas memberi tahu utas lain.Monitor.pulseAll()
: Sebuah utas memberi tahu semua utas lainnya dalam suatu prosessumber
Selain semua penjelasan di atas, kunci adalah pernyataan C # sedangkan Monitor adalah kelas .NET yang terletak di namespace System.Threading.
sumber