Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

List<T> thread safety

I am using the below code

var processed = new List<Guid>(); Parallel.ForEach(items, item =>  {     processed.Add(SomeProcessingFunc(item)); }); 

Is the above code thread safe? Is there a chance of processed list getting corrupted? Or should i use a lock before adding?

var processed = new List<Guid>(); Parallel.ForEach(items, item =>  {     lock(items.SyncRoot)         processed.Add(SomeProcessingFunc(item)); }); 

thanks.

like image 805
stackoverflowuser Avatar asked Feb 16 '11 18:02

stackoverflowuser


People also ask

Does List contain thread-safe?

If a writer may be writing at the same time, List. Contains is definitely not thread safe. You'll need to wrap it and any other reads and writes with a lock.

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.

Is reading a List thread-safe?

Yes, List<T> is fine to read from multiple threads concurrently, so long as nothing's writing.

Is Java List thread-safe?

Yes, these are thread-safe. Stack, Vector, Properties and Hashtable classes have all been implemented in Java 1.0, therefore they are mostly considered to be legacy classes.


1 Answers

No! It is not safe at all, because processed.Add is not. You can do following:

items.AsParallel().Select(item => SomeProcessingFunc(item)).ToList(); 

Keep in mind that Parallel.ForEach was created mostly for imperative operations for each element of sequence. What you do is map: project each value of sequence. That is what Select was created for. AsParallel scales it across threads in most efficient manner.

This code works correctly:

var processed = new List<Guid>(); Parallel.ForEach(items, item =>  {     lock(items.SyncRoot)         processed.Add(SomeProcessingFunc(item)); }); 

but makes no sense in terms of multithreading. locking at each iteration forces totally sequential execution, bunch of threads will be waiting for single thread.

like image 51
Andrey Avatar answered Oct 14 '22 14:10

Andrey