I may be missing some blindingly obvious documentation somewhere, but is static readonly member variable guaranteed to be initialized properly for use as a lock object?
In short, I have a library class that performs operation on an external resource that should only have a single instance touching it at any one time (don't have to worry about another process, it's only on a single process). The library class itself can have multiple instances in multiple threads, so in order to ensure that only one instance access said resource at a time, I need to use a lock.
I've seen a lot of lock object declaration like this.
private static readonly object _lockObj = new object();
Can this guarantee that multiple threads won't, by bad timing, initialize the two objects at the same time and lock on two objects? Or should I be creating the lock object like this.
private static readonly Lazy<object> _lockObj = new Lazy<object>(() => new object());
P.S. I'm referring to the C#'s lock(_lockObj){...} keyword for locking.
The runtime guarantees only one copy of a static member field. You can even use it without any instances of the class. It would be safe for use as a lock object.
Related
I have a problem adding a new item to a Static dictionary while using it from multiple threads. Any ideas where I'm doing it wrong?
Initializing the dictionary:
public static class Server
{
public static volatile Dictionary<int, List<SomeClass>> Values;
}
Trying to add an item:
Server.Values.Add(someInt, new List<SomeClass> { elements});
As explained by Jon Skeet you are using an object which is not guaranteed to be thread safe
try using ConcurrentDictionary which is designed for Concurrency Scenario With Many threads
public static class Server
{
public static ConcurrentDictionary<int, List<SomeClass>> Values =
new ConcurrentDictionary<int, List<SomeClass>>();
}
Here how to use it
bool added = Server.Values.TryAdd(someInt, new List<SomeClass> { elements});
In general, when working with resources that are shared between multiple threads, you need to use a synchronization mechanism, like lock() to make your code thread safe. Create a common object to use as the lock:
private object _lock = new object();
Then you surround any code which accesses your shared resource, like this:
lock(_lock)
{
// perform operations on shared resource here.
}
It's important to note that you should have a different lock for every shared resource rather than one lock used for all resources. If you use your lock object with multiple resources, your code could be very inefficient. If one thread grabs the lock so it can use resource A, then other threads will have to wait for the lock to be released even if they want to access resource B which has nothing to do with the resource A. Therefore, it's better to have one lock object per resource and to name your lock objects so you know which resources they should be used with.
An alternative to this (as BRAHIM Kamel's answer shows) is to use a replacement, if available, for your shared resource which already has thread synchronization baked in, like ConcurrentDictionary. Though this may not be feasible in your case.
This question already has answers here:
C# lock statement, what object to lock on?
(4 answers)
Closed 8 years ago.
I have seen few different ways of using a particular object for lock construct.
Have a dedicated private static local variable and lock on that
private static object syncObj = new object();
...
lock(syncObj)
{
}
Have a dedicated private local variable and lock on that
private object syncObj = new object();
...
lock(syncObj)
{
}
Another one is to use the object itself.
private List<MyClass> SomeObjects = new List<MyClass>();
....
lock(SomeObjects)
{
}
One approach is to use the type of a particular object.
private List<MyClass> SomeObjects = new List<MyClass>();
...
lock(SomeObjects.GetType())
{
}
Another possibility is using lock(this) but general recommendation seem to try to avoid using this.
My questions.
1. Are there any other ways of using objects for locks?
2. How can I decide of what approach should be used for a particular scenario?
If Marc Gravell's answer to C# lock statement, what object to lock on? were the top vote-getter (and it should have been, IMHO), I would happily have voted to close this question as a duplicate.
But, it's not. And this question does have some minor differences in context. So…
Taking your five examples in particular:
Have a dedicated private static local variable and lock on that
This works well for scenarios where you have some static member that needs to be synchronized. A common implementation convention in .NET is to make all static members thread-safe, and for types which are not themselves specifically targeting multi-threaded code, to not bother making instance members thread-safe.
Note that the declaration should be static readonly, to ensure that the locking object remains the same through the lifetime of the program.
Have a dedicated private local variable and lock on that
This is better for protecting instance members, in a class that is specifically supposed to be thread-safe. While a static lock object would also work, that can be needlessly contentious. That is, private instance members are generally safe from other instances of the object touching them, as classes usually only operate on their own instance members, not those of other instances.
A static lock object would require all threads operating on any instance to synchronize their execution, when it would be safe for threads using different instances to operate concurrently.
As with the static lock object, make the field readonly.
Another one is to use the object itself.
I tend to try to avoid doing this. If the object is maintained privately, and you are sure that the reference is never known to any other code other than your own and that within the object itself, it can be safe enough. But it can be risky, as you can't be sure even if the object is currently never used elsewhere that the code will never change such that it later.
If the reference were to become available outside your own class, then it's possible some other code could also lock on the object in an inopportune way. The worst would be if it acquired some other lock, then tried to lock on that object, while your own code tried to acquire the other lock having already locked on that object. Deadlock. Less bad is simply increasing thread contention on the lock. The code would still work, but may not run as well.
One approach is to use the type of a particular object
This combines the worst of the above: publicly available reference, static member. Strongly advised against.
Another possibility is using lock(this) but general recommendation seem to try to avoid using this.
This is just a variation on #3, except that you are practically guaranteed that the reference will be used by some other code. Not advised.
You can, in the sense that "it is possible", use any reference with a lock statement (i.e. any class value…you definitely should not use any struct value, as suggested in the answer to the question which Preston has suggested as a duplicate for this one). However, there are lots of ways to get this wrong.
IMHO, the best policy is to keep it simple: match the static/instance declaration of whatever it is you're trying to protect (either a whole object, or in some cases specific operations on a specific object), always make the field readonly, and be done with it.
I have been learning about locking on threads and I have not found an explanation for why creating a typical System.Object, locking it and carrying out whatever actions are required during the lock provides the thread safety?
Example
object obj = new object()
lock (obj) {
//code here
}
At first I thought that it was just being used as a place holder in examples and meant to be swapped out with the Type you are dealing with. But I find examples such as Dennis Phillips points out, doesn't appear to be anything different than actually using an instance of Object.
So taking an example of needing to update a private dictionary, what does locking an instance of System.Object do to provide thread safety as opposed to actually locking the dictionary (I know locking the dictionary in this case could case synchronization issues)?
What if the dictionary was public?
//what if this was public?
private Dictionary<string, string> someDict = new Dictionary<string, string>();
var obj = new Object();
lock (obj) {
//do something with the dictionary
}
The lock itself provides no safety whatsoever for the Dictionary<TKey, TValue> type. What a lock does is essentially
For every use of lock(objInstance) only one thread will ever be in the body of the lock statement for a given object (objInstance)
If every use of a given Dictionary<TKey, TValue> instance occurs inside a lock. And every one of those lock uses the same object then you know that only one thread at a time is ever accessing / modifying the dictionary. This is critical to preventing multiple threads from reading and writing to it at the same time and corrupting its internal state.
There is one giant problem with this approach though: You have to make sure every use of the dictionary occurs inside a lock and it uses the same object. If you forget even one then you've created a potential race condition, there will be no compiler warnings and likely the bug will remain undiscovered for some time.
In the second sample you showed you're using a local object instance (var indicates a method local) as a lock parameter for an object field. This is almost certainly the wrong thing to do. The local will live only for the lifetime of the method. Hence 2 calls to the method will use lock on different locals and hence all methods will be able to simultaneously enter the lock.
It used to be common practice to lock on the shared data itself:
private Dictionary<string, string> someDict = new Dictionary<string, string>();
lock (someDict )
{
//do something with the dictionary
}
But the (somewhat theoretical) objection is that other code, outside of your control, could also lock on someDict and then you might have a deadlock.
So it is recommended to use a (very) private object, declared in 1-to-1 correspondence with the data, to use as a stand-in for the lock. As long as all code that accesses the dictionary locks on on obj the tread-safety is guaranteed.
// the following 2 lines belong together!!
private Dictionary<string, string> someDict = new Dictionary<string, string>();
private object obj = new Object();
// multiple code segments like this
lock (obj)
{
//do something with the dictionary
}
So the purpose of obj is to act as a proxy for the dictionary, and since its Type doesn't matter we use the simplest type, System.Object.
What if the dictionary was public?
Then all bets are off, any code could access the Dictionary and code outside the containing class is not even able to lock on the guard object. And before you start looking for fixes, that simply is not an sustainable pattern. Use a ConcurrentDictionary or keep a normal one private.
The object which is used for locking does not stand in relation to the objects that are modified during the lock. It could be anything, but should be private and no string, as public objects could be modified externally and strings could be used by two locks by mistake.
So far as I understand it, the use of a generic object is simply to have something to lock (as an internally lockable object). To better explain this; say you have two methods within a class, both access the Dictionary, but may be running on different threads. To prevent both methods from modifying the Dictionary at the same time (and potentially causing deadlock), you can lock some object to control the flow. This is better illustrated by the following example:
private readonly object mLock = new object();
public void FirstMethod()
{
while (/* Running some operations */)
{
// Get the lock
lock (mLock)
{
// Add to the dictionary
mSomeDictionary.Add("Key", "Value");
}
}
}
public void SecondMethod()
{
while (/* Running some operation */)
{
// Get the lock
lock (mLock)
{
// Remove from dictionary
mSomeDictionary.Remove("Key");
}
}
}
The use of the lock(...) statement in both methods on the same object prevents the two methods from accessing the resource at the same time.
The important rules for the object you lock on are:
It must be an object visible only to the code that needs to lock on it. This avoids other code also locking on it.
This rules out strings that could be interned, and Type objects.
This rules out this in most cases, and the exceptions are too few and offer little in exploiting, so just don't use this.
Note also that some cases internal to the framework lock on Types and this, so while "it's okay as long as nobody else does it" is true, but it's already too late.
It must be static to protect static static operations, it may be instance to protect instance operations (including those internal to a instance that is held in a static).
You don't want to lock on a value-type. If you really wanted too you could lock on a particular boxing of it, but I can't think of anything that this would gain beyond proving that it's technically possible - it's still going to lead to the code being less clear as to just what locks on what.
You don't want to lock on a field that you may change during the lock being held, as you'll no longer have the lock on what you appear to have the lock on (it's just about plausible that there's a practical use for the effect of this, but there's going to be an impedance between what the code appears to do at first read and what it really does, which is never good).
The same object must be used to lock on all operations that may conflict with each other.
While you can have correctness with overly-broad locks, you can get better performance with finer. E.g. if you had a lock that was protecting 6 operations, and realised that 2 of those operations couldn't interfere with the other 4, so you changed to having 2 lock objects, then you can gain by having better coherency (or crash-and-burn if you were wrong in that analysis!)
The first point rules out locking on anything that is either visible or which could be made visible (e.g. a private instance that is returned by a protected or public member should be considered public as far as this analysis goes, anything captured by a delegate could end up elsewhere, and so on).
The last two points can mean that there's no obvious "type you are dealing with" as you put it, because locks don't protect objects, the protect operations done on objects and you may either have more than one object affected, or the same object affected by more than one group of operations that must be locked.
Hence it can be good practice to have an object that exists purely to lock on. Since it's doing nothing else, it can't get mixed up with other semantics or written over when you don't expect. And since it does nothing else it may as well be the lightest reference type that exists in .NET; System.Object.
Personally, I do prefer to lock on an object related to an operation when it does clearly fit the bill of the "type you are dealing with", and none of the other concerns apply, as it seems to me to be quite self-documenting, but to others the risk of doing it wrong out-weighs that benefit.
Why is it considered bad practice to lock non-static fields?
And, if I am not locking non-static fields, then how do I lock an instance method without locking the method on all other instances of the same or derived class?
I wrote an example to make my question more clear.
public abstract class BaseClass
{
private readonly object NonStaticLockObject = new object();
private static readonly object StaticLockObject = new object();
protected void DoThreadSafeAction<T>(Action<T> action)
where T: BaseClass
{
var derived = this as T;
if(derived == null)
{
throw new Exception();
}
lock(NonStaticLockObject)
{
action(derived);
}
}
}
public class DerivedClass :BaseClass
{
private readonly Queue<object> _queue;
public void Enqueue(object obj)
{
DoThreadSafeAction<DerivedClass>(x=>x._queue.Enqueue(obj));
}
}
If I make the lock on the StaticLockObject, then the DoThreadSafeAction method will be locked for all instances of all classes that derive from BaseClass and that is not what I want. I want to make sure that no other threads can call a method on a particular instance of an object while it is locked.
Update
Thank you all for your help : I have posted a another question as a follow up to some of the information you all provided. Since you seem to be well versed in this area, I have posted the link: What is wrong with this solution to locking and managing locked exceptions?
It's not about it being bad-practice, it's about what is your purpose.
Static fields are accessed (or, "common to") all the instances of that type. So locking such an static field enables you to control concurrency between all the instances of that type, or, the scope of concurrency control achieved is all the instances of that type.
However, if you lock a non-static field, the lock will only be active for that instance, so you control concurrency only within that instance, or, the scope of concurrency control achieved is the instance.
Now, whenever locking an object I go like this. What is the resource that I'm concurring for? Maybe it's database, maybe it's a bunch of instance fields that can't be changed while I doing a certain processing, etc. Once I know what is I'm locking myself out of, I check it's scope.
If it's an entity outside my application, then it's application scope. Everything must be locked out simultaneously.
If it's a bunch of instance fields, then it's instance scope.
If it's a bunch of static fields, then it's type scope.
So, for 1 and 3, use a static field. For 2, use a instance field.
Now, another thing: usually, for 1, you will have a single class that wraps around that resource. And, usually you will design that class as a singleton. Now, with singletons, this is funny: you are guaranteed, by design, to have only a single instance, so it doesn't matter whether you are locking a instance or static field.
PS.: If you are using a lock to protect the instantiation of the singleton, of course it should be static. (why?)
You are locking an object that is used as a lock.
The difference therefor is where the lock is contained (or its accessibility).
If you have it as a static member, it is accessible to all the objects of the same class. So you get a single lock, that will lock them all.
If you have it as member of the class (non static) then it is only accessible to that object. So you will get a single lock per object instance.
There's no good-bad practice in this case. It's just a question of what you want to achieve.
Just remember to avoid locking this in an object.
It is not bad to lock on instance fields. Some consider it bad to lock the instance itself, which is implicitely done by using synchronised on instance methods, but this is another story.
Locking on the instance (or "this") can have side effects if other classes also use the instance for locking. You just can be sure if you hold your own personal lock.
I'm using C# & .NEt 3.5. What is the difference between the OptionA and OptionB ?
class MyClass
{
private object m_Locker = new object();
private Dicionary<string, object> m_Hash = new Dictionary<string, object>();
public void OptionA()
{
lock(m_Locker){
// Do something with the dictionary
}
}
public void OptionB()
{
lock(m_Hash){
// Do something with the dictionary
}
}
}
I'm starting to dabble in threading (primarly for creating a cache for a multi-threaded app, NOT using the HttpCache class, since it's not attached to a web site), and I see the OptionA syntax in a lot of the examples I see online, but I don't understand what, if any, reason that is done over OptionB.
Option B uses the object to be protected to create a critical section. In some cases, this more clearly communicates the intent. If used consistently, it guarantees only one critical section for the protected object will be active at a time:
lock (m_Hash)
{
// Across all threads, I can be in one and only one of these two blocks
// Do something with the dictionary
}
lock (m_Hash)
{
// Across all threads, I can be in one and only one of these two blocks
// Do something with the dictionary
}
Option A is less restrictive. It uses a secondary object to create a critical section for the object to be protected. If multiple secondary objects are used, it's possible to have more than one critical section for the protected object active at a time.
private object m_LockerA = new object();
private object m_LockerB = new object();
lock (m_LockerA)
{
// It's possible this block is active in one thread
// while the block below is active in another
// Do something with the dictionary
}
lock (m_LockerB)
{
// It's possible this block is active in one thread
// while the block above is active in another
// Do something with the dictionary
}
Option A is equivalent to Option B if you use only one secondary object. As far as reading code, Option B's intent is clearer. If you're protecting more than one object, Option B isn't really an option.
It's important to understand that lock(m_Hash) does NOT prevent other code from using the hash. It only prevents other code from running that is also using m_Hash as its locking object.
One reason to use option A is because classes are likely to have private variables that you will use inside the lock statement. It is much easier to just use one object which you use to lock access to all of them instead of trying to use finer grain locks to lock access to just the members you will need. If you try to go with the finer grained method you will probably have to take multiple locks in some situations and then you need to make sure you are always taking them in the same order to avoid deadlocks.
Another reason to use option A is because it is possible that the reference to m_Hash will be accessible outside your class. Perhaps you have a public property which supplies access to it, or maybe you declare it as protected and derived classes can use it. In either case once external code has a reference to it, it is possible that the external code will use it for a lock. This also opens up the possibility of deadlocks since you have no way to control or know what order the lock will be taken in.
Actually, it is not good idea to lock on object if you are using its members.
Jeffrey Richter wrote in his book "CLR via C#" that there is no guarantee that a class of object that you are using for synchronization will not use lock(this) in its implementation (It's interesting, but it was a recommended way for synchronization by Microsoft for some time... Then, they found that it was a mistake), so it is always a good idea to use a special separate object for synchronization. So, as you can see OptionB will not give you a guarantee of deadlock - safety.
So, OptionA is much safer that OptionB.
It's not what you're "Locking", its the code that's contained between the lock { ... } thats important and that you're preventing from being executed.
If one thread takes out a lock() on any object, it prevents other threads from obtaining a lock on the same object, and hence prevents the second thread from executing the code between the braces.
So that's why most people just create a junk object to lock on, it prevents other threads from obtaining a lock on that same junk object.
I think the scope of the variable you "pass" in will determine the scope of the lock.
i.e. An instance variable will be in respect of the instance of the class whereas a static variable will be for the whole AppDomain.
Looking at the implementation of the collections (using Reflector), the pattern seems to follow that an instance variable called SyncRoot is declared and used for all locking operations in respect of the instance of the collection.
Well, it depends on what you wanted to lock(be made threadsafe).
Normally I would choose OptionB to provide threadsafe access to m_Hash ONLY. Where as OptionA, I would used for locking value type, which can't be used with the lock, or I had a group of objects that need locking concurrently, but I don't what to lock the whole instance by using lock(this)
Locking the object that you're using is simply a matter of convenience. An external lock object can make things simpler, and is also needed if the shared resource is private, like with a collection (in which case you use the ICollection.SyncRoot object).
OptionA is the way to go here as long as in all your code, when accessing the m_hash you use the m_Locker to lock on it.
Now Imagine this case. You lock on the object. And that object in one of the functions you call has a lock(this) code segment. In this case that is a sure unrecoverable deadlock