What exactly does locking on an object mean?

Although I use locks in my application, I don’t understand what exactly the lock does for a specific reference type. I thought that it just stops the thread until the contents of {} are finished. But I read that blocking (this) is bad, if its audience is why? The article explains this, but I don’t understand that I don’t know what happened with the fact that the object itself is locked. For example, what if I use lock (this) and from another thread, is called by its method? I thought that only the code under the lock is protected, or I won’t be able to access the locked object at all? Thanks

+4
source share
5 answers

Each object in the managed heap can be used as a lock object, which is a means of synchronizing access between threads.

I thought that it just stops the thread until the contents of {} are complete.

Well, a lock it stops other threads from locking the lock until the lock is released, which is most often at the end of the lock statement (but it can also be Monitor.Wait ).

Using lock(this) dangerous because locking is complex and understands exactly which threads are blocking, which object is very important at this time, in order to avoid deadlocks; however, if you lock(this) , you are not in control of other threads, which can also (unexpectedly) block the same object. It is much safer to use the private field to lock.

As an example, if you have (in a synchronized list):

 private IList<T> innerList = ... public int Count { get { lock(this) { return innerList.Count; } } } 

Then it’s easy to imagine another bit of code that also has a link to this synchronized list and a lock on it, for example:

 SyncList<T> list = ... lock(list) { // lock for atomicity if(!list.Contains(value)) list.Add(value); } 

This is a potential dead end; it would be much better if Count did not lock(this) , but blocked a private object, i.e.

 private readonly object syncLock = new object(); public int Count { get { lock(syncLock) { return innerList.Count; } } } 

Now there is no risk for this problem. Another problem is that both field events and [MethodImpl] call lock(this) . Locking on Type (for static methods) is equally dangerous for the same reasons.

+7
source

The object itself is not locked. Think about the fact that each object has an associated lock (or monitor). When one thread has acquired a lock, no other thread can receive it without the first thread releasing it, either by calling Monitor.Exit (which happens at the end of the lock statement) or by calling Monitor.Wait . The thread that calls Monitor.Enter to get the lock will block until it can get the lock.

The object itself is not protected at all - locks are mostly advisory.

The reason for not blocking this is because you don’t know what other code has a link to this. Obtaining the right to block requires that you know in which situations the thread will or will not own the lock - and you cannot know that if the code outside your control can take out the lock. The exception is that you publish the link for the explicit purpose of sharing locks (for example, the SyncRoot property in .NET 1.1 collections).

+5
source

Locking an object does nothing for the object itself - it simply means that any other thread trying to block the same object will be stopped until the blocking thread releases it. The reason why locking (this) is not approved is because other code outside the object can also block the object and thus interfere with its normal operation.

+1
source

When you use lock(someObject) { ...code... } , this means that only when the thread can be inside the locked area at a time (provided that you always lock the same object!). The second thread that is trying to enter the area will be blocked and must wait until the first thread leaves. If you have two lock (someObject) { } blocking the same object, only one thread can enter any of these areas.

A lock is usually an implementation detail that must remain confidential. It’s a bad idea to block an open member because it means that clients of your class can also block the same object, and this can lead to locks or unnecessary slowdowns. Locking on this bad for the same reason.

Create a private new object and lock it.

0
source
 using System; using System.Threading; class sycexp { public static void Main() { exp e=new exp(); Thread t1=new Thread(new ThreadStart(e.show)); Thread t2=new Thread(new ThreadStart(e.show)); t1.Name="First Thread"; t2.Name="Second Thread"; t1.Start(); t2.Start(); } } class exp { public object lockme=new object(); public void show() { lock(lockme) { Console.WriteLine("Start "+Thread.CurrentThread.Name.ToString()); Console.WriteLine("1"); Console.WriteLine("2"); Console.WriteLine("3"); Console.WriteLine("4"); Console.WriteLine("5"); Console.WriteLine(Thread.CurrentThread.Name.ToString()+" Stopped"); } } } 
0
source

All Articles