線程安全對象 - 靜態與否?

[英]Thread safety object - static or not?

I was recently in an interview and the tech guy asked me about how to make an application thread-safe.


Well, after explaining the lock() correctly, he said it is not a good idea to have the object as static.


private static readonly object _syncLock = new object();

He claimed the reason is that static makes that object slower for threads to lock than if it was non static. Is this true?


EDIT: Nonetheless I am still not sure. What is the difference between these three approaches?


private static readonly object _syncLock = new object();
public static readonly object _syncLock = new object();
private readonly object _syncLock = new object();

6 个解决方案


If a lock object should be static or not depends on the object you want to lock. If you want to lock an instance of a class you cannot use a static lock object. If you want to lock static data you cannot use an instance lock object. So there seems not to be any choice.


You could think about using a static or an instance lock object to lock the access to instance data, but this results in different behaviors. With an instance lock object you lock only an instance while an static lock object will lock all instances. So no choice for performance tuning here, too.



He claimed the reason is that static is run at runtime instead of compilation and would make that object slower for threads to lock than if it was non static.


This doesn't really make any sense - I think either the interviewer did not know what he was talking about, or maybe you misunderstood his point.

這沒有任何意義 - 我認為面試官不知道他在說什么,或者你誤解了他的觀點。


Sometimes in job interviews I say something I know is incorrect or something that is utter nonsense to see if the candidate will effectively argue his point or just give up and agree.


Oh and here's an excellent article by Jeffrey Richter on the proper uses of lock. :)

哦,這是傑弗里里希特關於正確使用鎖的一篇優秀文章。 :)


Use a non static object for the lock whenever you need to make sure the same instance isn't manipulated by different threads at the same time.


Lets say you have some List classes, with a special Reorder method that accepts some strange arguments. Consider if you need to reorder 100 different lists during some paralel processes. You only care that different threads don't manipulate the same list at the same time, as it might affect your reorder logic. You don't need a static lock, as you don't care when different lists are being manipulated at the same time.


A simple example of a scenario with a static lock, is initialization of some static data, where you want to make sure the load logic is ran only once. Like some Cache or a Singleton.



If you have only one instance of a class that shares between multiple threads, it's ok to use normal object. but if you have multiple objects of a class that share between multiple threads, you have to use static object.


On the other hand, with normal object you can manage concurrency for one instance of a class and with static object you can manage concurrency in the scope of all instances of a class.



The others are correct that the choice of using a static of instance field depends on what state (class-level or instance-level) that you need to lock, and there is no relevant difference in speed for the lock itself. BUT if you really only need to use instance data then your app could run much faster using lock(this) rather than locking out all threads from accessing the data of ANY instance. That might have been what the interviewer was getting at - in an application where multiple threads are only using instance data it should indeed run faster if you only lock the instance because it won't block other threads from using other instances.

其他正確的選擇使用靜態實例字段取決於您需要鎖定的狀態(類級別或實例級別),並且鎖定本身的速度沒有相關差異。但是如果你真的只需要使用實例數據那么你的app可以使用lock(this)運行得更快,而不是鎖定所有線程訪問任何實例的數據。這可能是面試官得到的 - 在一個多線程只使用實例數據的應用程序中,如果你只鎖定實例,它確實應該運行得更快,因為它不會阻止其他線程使用其他實例。

Conversely if threads are accessing class-level (static) state then you need to lock them all with a single object. When I need to do this, a pattern I've used is to lock the type of the class like this:


[Edit - not such a good idea after all, see comments below]

[編輯 - 畢竟不是一個好主意,請參閱下面的評論]

  // use class-level data

This avoids the necessity of creating the static object field.




粤ICP备14056181号  © 2014-2021 ITdaan.com