Variable scope for lock mechanism - c#

Can someone explain in detail why scope of the variable being lock matter?
For example:
lock(variable){ //do something here ! }
In msdn, it states to avoid locking public type and best to lock private or private static type. During the locking, what is actually being lock? The variable address or what?

lock accepts an instance of type System.Object. All instances of System.Object contain some hidden field in memory which is used for synchronization purposes (lets call it ThreadId). So, what happens when you call lock with some object? The lock statement (actually it is a syntax sugar for Monitor.Enter) checks whether the passed object has something in ThreadId field, and if it doesn't have anything, it puts there some identifier (id of current thread as far as I remember), enters the block of code under the lock statement and in the end of this block - resets the ThreadId value. If the ThreadId field is not empty, it stops and waits until it become empty. In such way it is guaranteed that only one thread can access the code section covered by lock with same passed object.
Why it is not recommended to use public properties/fields in lock? With locks, it is very easy to make a deadlock (when thread A waits for some action from thread B which in its turn waits for action from thread A). So, it is very important to control all locks made on same objects. When you design some class, you know about all private fields, only you can access them and only you can use them in locks. Once the field become public, you lose this control. Yes, you still can control all locks around this field inside your class, but you don't know how this field will be used by consumers of your class, they also can use it for locks and thus cause the deadlock.

This variable is just some kind of a unique tag. Making it private avoid incidental locking with the same tag somewhere else.
And some comments regarding internal lock implementation can be found here:
http://blogs.msdn.com/b/junfeng/archive/2004/02/18/75454.aspx

If you lock on a private member in a particular object you are only locking in that instance. If you lock on a static field you will lock in all instances of the object.

Related

Lock scope in C#: is returned object still "locked"?

Assuming I have an object A containing
// ...
private List<double> someList = new List<double>();
// ...
public List<double> SomeList
{
get { lock (this) { return someList; } }
}
// ...
would it be thread safe to perform operation on the list as in the code below. Knowing that several operations could be executed simultaneously by different threads.
A.SomeList.Add(2.0);
or
A.SomeList.RemoveAt(0);
In other words, when is the lock released?
There is no thread safety here.
The lock is released as soon as the block it protects is finished, just before the property returns, so the calls to Add ad RemoveAt are not protected by the lock.
The lock you shown in the question isn't of much use.
To make list operations thread safe you need to implement your own Add/Remove/etc methods wrapping those of the list.
public void Add(double item)
{
lock(_list)
{
_list.Add(item);
}
}
Also, it's a good idea to hide the list itself from the consumers of your class, i.e. make the field private.
The lock is released when you exit the body of the lock statement. That means that your code is not thread-safe.
In other words, you can be sure that two threads won't be executing return someList on the same object at the same time. But it's certainly possible that one thread will execute Add() at the same time as another thread will execute RemoveAt(), which is what makes it non thread-safe.
The lock is released when the code inside the lock is finished executing.
Also, locking on this will only affect the current instance of the object
Ok, just for the hell of it.
There IS a way to make your object threadsafe, by using architectures that are already threadsafe.
For example, you could make your object a single threaded COM object. The COM object will be thread safe, but you'll pay with performance (the price of being lazy and not managing your own locks).
Create a COM Object in C#
...others said already, but just to formalize a problem a bit...
First, lock (this) {...} suggests a 'scope' - e.g. like using (){} - it only locks (this in this case) for variables inside. And that's a 'good thing' :) actually, as if you couldn't rely on that the whole locks/synchronization concept would be very much useless,
lock (this) { return something; } is an oxymoron of a sort - it's returning something that unlocks the very same moment it returns,
And the problems I think is the understanding of how it works. 'lock()' is not 'persisted' in a state of the object, so that you could return it etc. Take a look here how it's implemented How does lock work exactly? - answer explains it. It's more of a 'critical section' - i.e. you protect certain parts of 'code', which uses the variable - not the variable itself. Any type of synchronization requires 'synchronization objects' to hold the locks - and to be disposed of once lock is no longer needed. Take a look at this post https://stackoverflow.com/a/251668/417747, Esteban formulated that very well,
"Finally, there is the common misconception that lock(this) actually modifies the object passed as a parameter, and in some way makes it read-only or inaccessible. This is false. The object passed as a parameter to lock merely serves as a key" (this is a quote)
you either (usually) lock 'private code' of a class method, property... - to synchronize access to something you're doing inside - and access being to a private member (again usually) so that nobody else can access it w/o going through your synchronized code.
Or you make a thread-safe 'structure' - like a list - which is already 'synchronized' inside so that you can access it in a thread-safe manner. But there are no such things (or not used, almost never) as passing locks around or having one place lock the variable, while the other part of the code unlocks it etc. (in that case it's some type of EventWaitHandle that's rather used to synchronize things in between 'distant' code where one fires off on another etc.)
In your case, the choice is I think to go with the 'synchronized structure', i.e. the list that's internally handled,

Lock on an object that might change during code execution

Let's suppose I have a thread that locks on an object reference
Thread #1
lock(myObj) { ... }
later in code I have myObj = new XYZObj();
and then Thread #2 locks on it
lock(myObj) { ... }
Will this code be thread safe, if the object reference has changed? When the object reference changes, the first lock is still valid?
Locks work on instances, not variables.
The lock statement will hold its own reference to the instance so that it will only exit the instance you entered.
The spec says:
where x is an expression of a reference-type, is precisely equivalent
to
System.Threading.Monitor.Enter(x);
try {
...
}
finally {
System.Threading.Monitor.Exit(x);
}
except that x is only evaluated once.
If you re-assign the variable between the two locks, you will get two valid locks on two different instances.
In general, however, you should never do that; it's a recipe for subtle bugs and race conditions.
You should only lock on dedicated readonly lock objects.
No. They will both be locking on different objects.
According to MSDN
Best practice is to define a private object to lock on, or a private
static object variable to protect data common to all instances.
Will this code be thread safe
The statement lock(myObj) { ... } is only safe until a new object reference is assigned to the myObj variable. Addition: Also, it's only safe if any data shared between threads that is used non-atomically mutating inside a lock on an object is only used non-atomically mutating inside locks on that same object.
So, every time you enter a lock for myObj, the actual referenced object is what is being used for the lock, not your variable. If you change the variable to reference a new object, then you're effectively locking different objects in different locks, which obviously isn't what you wanted. But, then again, the next time you come back to the first lock, the first and second lock object might be in sync again, and so it'll be safe again. Maybe!
As you can see, that behavior is completely broken. Is this a hypothetical question or are you really doing like that?

What is exactly a "thread-safe type"? When do we need to use the "lock" statement?

I read all documentation about thread-safe types and the "lock" statement, but I am still not getting it 100%.
When exactly do I need to use the "lock" statement? How it relates to (non) thread-safe types? Thank you.
Imagine an instance of a class with a global variable in it. Imagine two threads call a method on that object at exactly the same time, and that method updates the global variable inside.
The likelihood is that value in the variable will get corrupted. Different languages and compilers/interpreters will deal with this in different ways (or not at all...) but the point is that you get "undesired" and "unpredictable" results.
Now imagine that the method obtains a "lock" on the variable before attempting to read from or write to it. The first thread to call the method will get a "lock" on the variable, the second thread to call the method will have to wait until the lock is released by the first thread. While you still have a race condition (i.e. the second thread might overwrite the value from the first) at least you have predictable results because no two threads (that are unaware of each other) can modify the value at the same time.
You use the lock statement to obtain that lock on the variable. Typically you'd define a separate object variable and use that for the lock object:
public class MyThreadSafeClass
{
private readonly object lockObject = new object();
private string mySharedString;
public void ThreadSafeMethod(string newValue)
{
lock (lockObject)
{
// Once one thread has got inside this lock statement, any others will have to wait outside for their turn...
mySharedString = newValue;
}
}
}
A type is deemed "thread-safe" if it applies the principle that no corruption will occur if shared data is accessed by multiple threads at the same time.
Beware the difference between "immutable" and "thread-safe". Thread-safe says that you have coded for the scenario and won't get corruption if two threads access shared state at the same time, whereas immutability is simply saying you return a new object rather than modifying it. Immutable objects are thread-safe, but not all thread-safe objects are immutable.
Thread safe code means code that can be accessed with many threads and still operate correctly.
In C#, this normally requires some sort of synchronization mechanism. A simple one is the lock statement (which is behind the scenes a call to Monitor.Enter). A code block that is surrounded by a lock block can only be accessed by one thread at a time.
Any use of a type that is not thread safe requires you to manage synchronization yourself.
A good resource to learn about threading in C# is the free eBook by Joe Albahari, found here.
http://en.wikipedia.org/wiki/Thread_safety

how to use lock on a IList

I have a static collections which implements IList interface. This collection is used throughout the application, including adding/removing items.
Due to multithread issue, I wonder what I can do to ensure that the list is modifying one at a time, such as when 1 thread try to add an item, another thread should not do delete item at that time.
I wonder what is difference between lock(this) and lock(privateObject) ? Which one is better in my case?
Thank you.
The lock(this) will lock on the entire instance while lock(privateObject) will only lock that specific instance variable. The second one is the better choice since locking on the entire instance will prevent other threads from being able to do anything with the object.
From MSDN:
In general, avoid locking on a public
type, or instances beyond your code's
control. The common constructs lock
(this), lock (typeof (MyType)), and
lock ("myLock") violate this
guideline:
lock (this) is a problem if the
instance can be accessed publicly.
lock (typeof (MyType)) is a problem if
MyType is publicly accessible.
lock(“myLock”) is a problem since any
other code in the process using the
same string, will share the same lock.
Best practice is to define a private
object to lock on, or a private static
object variable to protect data common
to all instances.
In this particular case, the collection is static which effectively means there is a single instance but that still doesn't change how the lock(this) and lock(privateObject) would behave.
By using lock(this) even in a static collection you are still locking the entire instance. In this case, as soon as thread A acquires a lock for method Foo() all other threads will have to wait to perform any operation on the collection.
Using lock(privateObject) means that as soon as thread A acquires a lock for method Foo() all other threads can perform any other operation except Foo() without waiting. Only when another thread tries to perform method Foo() will it have to wait until thread A has completed its Foo() operation and released the lock.
The lock keyword is a little confusing. The object expression in the lock statement is really just an identification mechanism for creating critical sections. It is not the subject of the lock nor is it in any way guarenteed to be safe for multithreaded operations just because it is referenced by the statement.
So lock(this) is creating a critical section identified by the class containing the currently executing method whereas lock(privateObject) is identified by an object that is (presumably anyway) private to the class. The former is more risky because a caller of your class could inadvertantly define their own critical sections using a lock statement that uses that class instance as the lock object. That could lead to unintended threading problems including, but not limited to, deadlocks and bottlenecks.
You mentioned that you were concerned with multiple threads modifying the collection at the same time. I should point out that you should be equally concerned with threads reading the collection as well even if they are not modifying it. It is likely that you will need some of the same safe guards in place to protect the collection during reads as you would during writes.
Add a private member to the class that methods lock on.
eg.
public class MyClass : IList
{
private object syncRoot = new object();
public void Add(object value)
{
lock(this.syncRoot)
{
// Add code here
}
}
public void Remove(object value)
{
lock(this.syncRoot)
{
// Remove code here
}
}
}
This will ensure that access to the list is syncronized between threads for the adding and removing cases, while maintaining access to the list. This will still let enumerators access the list while another thread can modify it, but that then opens another issue where an enumerator will throw an exception if the collection is modified during the enumeration.

Modify locked object within lock block

I'm having thread contention in an OLTP app. While reviewing the code involved, I found the following:
lock (_pendingTransactions)
{
transaction.EndPointRequest.Request.Key = (string)MessageComparer.GenerateKey(transaction.EndPointRequest.Request);
if (!_pendingTransactions.ContainsKey(transaction.EndPointRequest.Request.Key))
{
_pendingTransactions.Add(transaction.EndPointRequest.Request.Key, transaction);
return true;
}
else
{
return false;
}
}
As you can see in the snippet, there is a lock on an object that is modified within the 'lock' block. Is there anything bad with that? Anyone had problems doing something like this?
Using locking in this way is often discouraged, with the recommendation being to use a dedicated lock field (class member variable). A dedicated lock field is of type Object and usually looks like this:
private object _pendingTransactionLock = new object();
If the object itself has some threading awareness, this lock variable might belong in _pendingTransaction's implementation class. Otherwise, it might belong alongside _pendingTransaction in the field's declaring class.
You don't say what type _pendingTransaction is. If this is a built-in collection class that provides a SyncRoot property, that might be a good choice to lock on.
See Jon Skeet's Choosing What to Lock On.
Generally speaking, one will take a lock on an object specifically because one is going to modify (or read) it, so there's nothing inherently wrong with this.
Probably the key generation can be taken outside the lock block, to reduce the duration of the lock. Other than that, this is an almost canonical example of lock that protects a list/collection/array: acquire lock, check if the key exists, add key if not already present, release the lock.

Categories