I'm currently programming my own implementation of priority queue / sorted list and I would like to have it concurrent.
In order to have it thread safe I'm using lock(someObject)
and I would like to verify some behavior of mutexes in C#.
Inner representation of my sorted list is basically linked list with head
and slots linked together.
Something like:
internal class Slot
{
internal T Value;
internal Slot Next;
public Slot(T value, Slot next = null)
{
Value = value;
Next = next;
}
}
Every time I'm manipulating with head
I have to use lock(someObject)
because of thread safety.
In order to implement ICollection
interface I have to implement public IEnumerator<T> GetEnumerator()
. In this method I have take my head
and read from it so I should use mutex.
public IEnumerator<T> GetEnumerator()
{
lock (syncLock)
{
var curr = head;
while (curr != null)
{
yield return curr.Value;
curr = curr.Next;
}
}
}
My question is: Is syncLock
locked for whole time in enumerator (so it will be unlocked after reaching end of the method) or it is automatically unlocked after yielding value?
What is a concurrent queue? A concurrent queue allows us to execute multiple tasks at the same time. Tasks will always start in the order they're added but they can finish in a different order as they can be executed in parallel. Tasks will run on distinct threads that are managed by the dispatch queue.
Concurrent namespace. This has several collection classes that are thread-safe and scalable. These collections are called concurrent collections because they can be accessed by multiple threads at a time.
Note that both ConcurrentStack and ConcurrentQueue classes are thread safe and they can manage locking and synchronization issues internally. You can also convert the concurrent queue instance to an array by making a call to the ToArray() method.
The ConcurrentBag class is used to create a thread-safe, unordered collection of data in C#. The ConcurrentBag class is very similar to the List in C# and can be used as a thread-safe list in C#.
Returns an enumerator that iterates through the ConcurrentDictionary<TKey,TValue>. An enumerator for the ConcurrentDictionary<TKey,TValue>. The enumerator returned from the dictionary is safe to use concurrently with reads and writes to the dictionary, however it does not represent a moment-in-time snapshot of the dictionary.
System. Collections. Concurrent System. Collections. Concurrent Returns an enumerator that iterates through the ConcurrentDictionary<TKey,TValue>. An enumerator for the ConcurrentDictionary<TKey,TValue>.
The problems which occurs while using Collections in Multi-threaded application: Most of the Collections classes objects (like ArrayList, LinkedList, HashMap etc) are non-synchronized in nature i.e. multiple threads can perform on a object at a time simultaneously. Therefore objects are not thread-safe.
(In ConcurrentDictionary this limit is when the size of the largest bucket is greater than the number of buckets for each lock. This check is done at the end of the TryAddInternal method.) Resizing the bucket array and re-hashing everything affects every bucket in the collection.
Thank you guys from the comments, here's sum up.
Answer: yes, syncLock
will be locked for the whole time → hence, it's a really bad idea
Possible solution:
true
while enumerating over the collection and throw exception when Add
, Clear
or Remove
methods are called -> this is default List
behavior @ManfredRadlwimmerIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With