Lock ConcurrentDictionary value

Separation is a small class that I created. I have thousands of sections that are in ConcurrentDictionary called Partitions. Before serializing, I want to lock a specific partition, do some work, and then unlock the partition.

During this time, no other thread will be able to access this section. Since my Partition class is a reference type, I wonder if I can lock one Partition object, as in the code below?

Will this block other threads from the same section in the ConcurrentDictionary sections during blocking below?

I do not want to block the use of a class-level lock object. My thought process is that multiple threads should be able to run the code below at the same time. They simply should not have access to a specific section if it is locked ...

private void serializePartition(int partNo) { Partition p; //Get a reference to the partition, lock, and save it to disk. lock (p = Partitions[partNo]) { using (var file = File.Create(dataPath + tableName + partNo + ".ppmi")) { Serializer.Serialize(file, p); } //decrement _CurrentRecordsInMemory by the size of the partition. Interlocked.Add(ref _CurrentRecordsInMemory, p.Data.Count * -1); //Clear the partitions data to free up memory and reset partition variables p.Data = null; p.OnDisk = true; p.StartCount = 0; } } 
+4
source share
2 answers

Your current implementation will block this Partition at this point in the function code. Another thread will still be able to access this Partition if the thread does not execute serializePartition (). Seeing that you are using ConcurrentDictionary, it is thread safe, so there should be no problem.

+2
source

I do not understand why other threads cannot access the section if they DO NOT also use lock on the section object. In other words, any other stream: Partitions[partNo] can access partion except when it is ALSO:

 lock (p = Partitions[partNo]) { //DO SOM STUFF ONLY WHEN YOU GOT ACCESS TO THE LOCK } 

To clarify:

The lock will only contain other threads that ALSO try to lock the same object. This does not prevent access from threads that are not trying to lock the object.

To correct this situation, you can use, perhaps, an event to block other threads from accessing the section object and set this event before you start serializing, and reset move or simply remove the object from ConcurrentDictionary while working on it and set it then. Only what suits your needs.

0
source

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


All Articles