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?
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.