Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List.Add() thread safety

Tags:

c#

asp.net

I understand that in general a List is not thread safe, however is there anything wrong with simply adding items into a list if the threads never perform any other operations on the list (such as traversing it)?

Example:

List<object> list = new List<object>(); Parallel.ForEach(transactions, tran => {     list.Add(new object()); }); 
like image 697
e36M3 Avatar asked Apr 08 '11 00:04

e36M3


People also ask

Is adding to list thread-safe?

That code will cause danger. Very simply, there are no atomic operations when adding to a list, at the least the "Length" property needs to be updates, and item needs to be put in at the right location, and (if there's a separate variable) the index needs to be updated. Multiple threads can trample over each other.

Is adding to a list thread-safe python?

A list can be made thread-safe using a mutual exclusion (mutex) lock. Specifically, each add, delete, update, and read of the list must be protected by a lock.

Is .NET list thread-safe?

NET Framework 4 introduces the System. Collections. Concurrent namespace, which includes several collection classes that are both thread-safe and scalable. Multiple threads can safely and efficiently add or remove items from these collections, without requiring additional synchronization in user code.

Why are lists not thread-safe?

In fact, by default, classes are not thread-safe. Being thread-safe would mean that any operation modifying the list would need to be interlocked against simultaneous access. This would be necessary even for those lists that will only ever be used by a single thread. That would be very inefficient.


2 Answers

Behind the scenes lots of things happen, including reallocating buffers and copying elements. That code will cause danger. Very simply, there are no atomic operations when adding to a list, at the least the "Length" property needs to be updates, and item needs to be put in at the right location, and (if there's a separate variable) the index needs to be updated. Multiple threads can trample over each other. And if a grow is required then there is lots more going on. If something is writing to a list nothing else should be reading or writing to it.

In .NET 4.0 we have concurrent collections, which are handily threadsafe and don't require locks.

like image 184
Talljoe Avatar answered Sep 20 '22 20:09

Talljoe


You current approach is not thread-safe - I would suggest avoiding this altogether - since you basically do a data transformation PLINQ might be a better approach ( I know this is a simplified example but in the end you are projecting each transaction into another "state" object).

List<object> list = transactions.AsParallel()                                 .Select( tran => new object())                                 .ToList(); 
like image 36
BrokenGlass Avatar answered Sep 23 '22 20:09

BrokenGlass