Locking an object inside a property, C #

public ArrayList InputBuffer { get { lock (this.in_buffer) { return this.in_buffer; } } } 

this.in_buffer is blocked while calling InputBuffer.Clear?

or the property simply blocks the in_buffer object while it receives a reference to it; lock ends and then this link is used to clear?

+4
source share
4 answers

In addition to what others have said about the scope of the lock, remember that you are not locking the object, you are locking only based on the instance of the object.

A common practice is to have a separate blocking mutex, as Jon Skeet illustrates.

If you need to guarantee synchronized execution while cleaning the collection, output a method that will clear the collection, call its clients and not reveal your main implementation details. (In any case, this is good practice - find encapsulation.)

+1
source

No, the property blocks the link when this link is received. Pretty pointless, to be honest ... this is more common:

 private readonly object mutex = new object(); private Foo foo = ...; public Foo Foo { get { lock(mutex) { return foo; } } } 

This lock will only cover access to its own resource and will not provide any protection for operations performed using Foo . However, this is not the same as not having a lock at all, because as long as a variable is written only with the same lock, it ensures that any time you read the Foo property, you get access to the most recent value from the property ... without blocking, there is no memory barrier, and you can get an "outdated" result.

This is pretty weak, but worth knowing.

Personally, I try to make very few types thread safe, and they have more appropriate operations ... but if you want to write code that modified and read properties from multiple threads, this is one way to do this, Using volatile can help too, but the semantics of this The method is disgustingly subtle.

+4
source

The object is locked inside the lock call brackets, and then it is unlocked.

In this case, the only code in the call to block is return this.in_buffer; .

Thus, in this case, in_buffer is not blocked during a call to InputBuffer.Clear.

One solution to your problem using extension methods is as follows.

 private readonly object _bufLock; class EMClass{ public static void LockedClear(this ArrayList a){ lock(_bufLock){ a.Clear(); } } } 

Now that you do:

 a.LockedClear(); 

A call to Clear will be blocked.

You must make sure that the buffer is only accessible inside _bufLocks.

+2
source

As already mentioned, this form of locking does not help.

 public ArrayList InputBuffer { get { lock (this.in_buffer) { return this.in_buffer; } } } 

Because it only blocks the link to the ArrayList, not the ArrayList itself. The lock(x) { } construct may be a little misleading. It does not change (block) state x any way.

It seems that you need:

 private ArrayList _inBuffer; private object _bufferLock; public object GetItem(int x) { lock (_bufferLock) { return _inBuffer[x]; } } public void SetItem(int x, object value) { lock (_bufferLock) { _inBuffer[x] = value; } } 

And similar methods around _inBuffer.Clear() , etc.

+1
source

Source: https://habr.com/ru/post/1340984/


All Articles