开发者

C# sharing locks with multithreading

Is there a common way to "share" a lock between different objects operating on same set of data?

I am aware that having a public object for locking is usually not recommended.

For example, a Queue could be implemented as thread safe, but some other class开发者_开发问答 might need a specific lock in order to lock several Queue operations. What happens if I have a third class, which also needs to make several locked operations on this same Queue instance?

For example: (let's say that L<T> is a thread-safe list, just to save some typing)

class Worker
{
    private readonly L<Something> _list;
    public Worker(L<Something> list) { _list = list; }

    private readonly object _lock = new object();
    public void Replace(Something old, Something new)
    {
       lock (_lock) 
       {
          if (_list.Contains(old))
          {
              _list.Remove(old);
              _list.Add(new);
          }
       }
    }
}

If some other class, on a different thread, removes the old element just after the if condition, list will no longer contain the element, as _lock is a private object.

Should I lock on the actual list instance?


Don't expose this list as a property, only the methods to interact with it. Then you can handle all of the locking within the one class and not deal with a public lock object.


A common way is to expose a property such as ICollection.SyncRoot. Of course, everyone has to obey the lock in order for this to work.

If you can possibly avoid this, and encapsulate the operations as ck suggests, that will be a lot more robust and easy to understand.


Technically you can easily expose the lock object. The problem with this is that the real reason for the recommendation of not making them public is the deadlocks.

If the lock object is exposed it introduces the risk that some other code will lock on this object with no regard to the locking ordering. This in turn can lead to deadlocks.

The same danger exists even if the locks are not exposed explicitly.

The best approach is not to expose the locks at all - neither implicitly nor explicitly. In other words bury them completely inside the class providing services. Unfortunately sometimes this is not an option.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜