How do I lock when the ideal scope of the lock object is known only at runtime?
How do I lock when the ideal scope of the lock object is known only at runtime?
The requirement is fairly straightforward: I want to make sure multiple threads aren't modifying an object at the same time. The tricky part is that the object is coming from a factory whose implementation is unknown until runtime. It may return a singleton, may create a new instance each time, or may have a pool of shared instances.
var thing = factory.Get(...);
lock (???) {
// modify thing
}
I understand it's not safe to lock on a public object that other code could potentially lock on, thus creating a possibility for deadlocks. In other words, I shouldn't lock (thing)
. But ideally I want to lock on something with the same, known-only-at-runtime scope of thing
.
lock (thing)
thing
One potential solution I came up with is to use a ConcurrentDictionary
of objects keyed by thing
's hashcode:
ConcurrentDictionary
thing
private static ConcurrentDictionary<int, object> _thingLocks =
new ConcurrentDictionary<int, object>();
...
var thing = factory.Get(...);
var thingLock = _thingLocks.GetOrAdd(thing.GetHashCode(), new object())
lock (thingLock) {
// modify thing
}
Intuitively I think this should work, because a) the locks themselves are in a private collection so nothing external could also be locking on them, and b) lock instances should be 1-to-1 with thing
instances. But since this sort of code is very difficult to test, I wanted to ask: is this a correct and appropriate solution? Is there a better/preferred method of locking on a scope that is known only at runtime?
thing
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.