ID lock only

I have a method that should run exclusivley to run a block of code, but I want to add this restriction only if it is really necessary. Depending on the value of Id (Int32), I would load / modify various objects, so it makes no sense to block access for all threads. Here's the first attempt to do this -

private static readonly ConcurrentDictionary<int, Object> LockObjects = new ConcurrentDictionary<int, Object>(); void Method(int Id) { lock(LockObjects.GetOrAdd(Id,new Object()) { //Do the long running task here - db fetches, changes etc Object Ref; LockObjects.TryRemove(Id,out Ref); } } 

I have doubts that this will work - TryRemove may fail (which will cause ConcurrentDictionary to continue to grow).

A more obvious error is that TryRemove successfully deletes the object, but if there are other threads (for the same Id) that are waiting (blocked) on this object, and then a new thread appears with the same identifier, adds a new object and starts processing, since no one else waits until the object is simply added.

Should I use TPL or some ConcurrentQueue to queue my tasks instead? What is the easiest solution?

+4
source share
2 answers

I use a similar approach to lock resources for related items, not to lock a resource ... It works great.

Yours is almost there, but you really don't need to remove the object from the dictionary; just let the next object with this id get the object lock.

Of course, is there a limit on the number of unique identifiers in your application? What is this limit?

+3
source

The main semantic problem that I see is that an object can be locked without being specified in the collection, because the last line in the lock deletes it, and the waiting thread can pick it up and lock it.

Modify the collection as a collection of objects that should protect the lock. Do not call it LockedObjects and do not remove objects from the collection unless you no longer expect the object to be needed.

I always think of this type of object as a key instead of a lock or a locked object; the object is not locked, it is the key to blocked code sequences.

+1
source

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


All Articles