[英]Why is specifying a synchronization object in the lock statement mandatory
我試圖圍繞lock語句中究竟發生的事情。
如果我理解正確,鎖定語句是語法糖和以下......
Object _lock = new Object();
lock (_lock)
{
// Critical code section
}
...被翻譯成大致類似的東西:
Object _lock = new Object();
Monitor.Enter(_lock);
try
{
// Critical code section
}
finally { Monitor.Exit (_lock); }
我已經使用了幾次lock語句,並且總是創建一個私有字段_lock
,作為專用的同步對象。 我明白為什么你不應該鎖定公共變量或類型。
但是為什么編譯器也不會創建該實例字段呢? 我覺得事實上可能存在開發人員想要指定鎖定內容的情況,但根據我的經驗,在大多數情況下,這絕對沒有興趣,你只需要鎖定! 那么為什么鎖沒有無參數過載?
lock()
{
// First critical code section
}
lock()
{
// Second critical code section
}
將被翻譯成(或類似):
[DebuggerHidden]
private readonly object _lock1 = new object()
[DebuggerHidden]
private readonly object _lock2 = new object()
Monitor.Enter(_lock1);
try
{
// First critical code section
}
finally { Monitor.Exit(_lock1); }
Monitor.Enter(_lock2);
try
{
// Second critical code section
}
finally { Monitor.Exit(_lock2); }
編輯 :我顯然不清楚多個鎖定語句。 更新了包含兩個鎖定語句的問題。
需要存儲鎖的狀態 。 是否輸入。 這樣可以阻止嘗試進入同一個鎖的另一個線程。
這需要一個變量。 只是一個非常簡單的,一個普通的對象就足夠了。
對這樣一個變量的一個硬性要求是它是在任何lock語句使用它之前創建的。 試圖在你提出的時候即時創建它會產生一個新問題,現在需要使用一個鎖來安全地創建變量,這樣只有進入鎖的第一個線程才能創建它,而其他線程試圖進入鎖被鎖定,直到它被創建。 這需要一個變量。 Etcetera,一個無法解決的雞蛋問題。
在某些情況下,您需要兩個不同的lock
,它們彼此獨立。 意思是當一個“可鎖定”的代碼部分被鎖定時,其他“可鎖定”不應該被鎖定。 這就是為什么有能力提供鎖定對象 - 你可以將它們中的幾個用於幾個獨立lock
為了使無變量的東西起作用,你必須要么:
此外,您還有一個問題,即決定這些應該是實例級還是靜態級。
最后,我猜測語言設計者並不認為在一個特定情況下的簡化值得在閱讀代碼時引入歧義。 線程代碼(這是使用鎖的原因)已經很難正確編寫並驗證。 讓它變得更難將是一件不好的事情。
允許隱式鎖定對象可能會鼓勵使用單個鎖定對象,這被認為是不好的做法。 通過強制使用顯式鎖對象,該語言鼓勵您將鎖命名為有用的東西,例如“countIncementLock”。
這樣命名的變量不會鼓勵開發人員在執行完全獨立的操作時使用相同的鎖對象,例如寫入某種流。
因此,對象可以在一個線程上寫入流,同時在另一個線程上遞增計數器,並且這兩個線程都不一定會相互干擾。
語言不能這樣做的唯一原因是因為它看起來像是一種好習慣,但實際上是隱藏了一種不好的做法。
編輯:
也許C#的設計者不想要隱式鎖變量,因為他們認為它可能會鼓勵不良行為。
也許設計師根本沒有想到隱式鎖定變量,因為他們首先要考慮其他更重要的事情。
如果每個C#開發人員確切地知道他們寫入lock()
時發生了什么,並且他們知道其含義,那么它就沒有理由不存在,也沒有理由說它為什么不應該按照你的建議工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.