views:

820

answers:

5

I filled several list<> with default values, stuck them into a struct then pass the struct into several threads. Each thread has a different range so thread 1 would access list[0 to 199] thread 2 would access [200 - 400] etc. Would i need a lock? and when do i need it? i can access the list with my multiple threads w/o using a lock. But if my main thread wants to read the data in the list (never write) do i need a lock for that? i'm sure i dont but i would like to ask before implementation.

-edit-

Thanks guys, you answered my question. (I will accept one later as long as someone doesnt disprove current answers)

+1  A: 

If you're absolutely sure you are not modifying the actual lists (adding items, removing items, etc) you don't need a lock.

Peter Lillevold
+6  A: 

If you're not modifying the collection, you won't need locking at all.

If you want to modify the collection with one of the threads, you might want to look at the ReaderWriterLock.

Peter's comment is a notable one. As also noted by the MSDN link above, you should consider using ReaderWriterLockSlim class if you're on .NET 3.5. The idea is the same, nevertheless.

Mehrdad Afshari
Or the new and improved ReaderWriterLockSlim http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim.aspx
Peter Lillevold
Make sure you run tests though -- if you're not holding the locks long enough to cause much contention, a standard lock may end up actually being quicker. If you're getting virtually no contention, a SpinLock (new in PFX/.NET 4.0) may be an even better option in the future.
Jonathan
@Jonathan, absolutely. On massively parallel platforms, SpinLocks almost always perform better
Mehrdad Afshari
+2  A: 

You don't need a lock if you don't write. However if you are writting in the other threads then you should have a lock. Even if those threads only access specific ranges, if you add nodes to the list that can cause problems. If you are not altering the list structure but only changing whatever its in the nodes then I don't think there is a problem.

Megacan
That's not true. Another thread could delete or modify your collection while you are reading it
Chad Grant
I think Megacan meant, if the threads only set values in the list, as in list[i] = value, AND it's always different indexes for different threads AND there's no other changes going on, it should be thread-safe without locks. Should doesn't mean it actually is though - I don't know the internals of List<> well enough to say that it's thread-safe. I think in that case though, an array should be used - and an array is thread safe in this context.
configurator
A List<T> whose size is not changing is thread-safe under the current implementation (it's an array internally). If you're changing the size, it's not thread-safe (as that array may have to be re-allocated for any add).
Jonathan
I should have pointed out though -- yes, an array would be better in this case. That way you aren't relying on the implementation of List<T> to use an array internally.
Jonathan
He says in his post, the threads would access different parts of the list. My answer had that in consideration
Megacan
A: 

Have you considered using arrays? An array is thread-safe as long as you don't access the same index in two threads. Also, it is quicker if you don't change the size.

configurator
A: 

In your struct object, I would at least mark the variable as ReadOnly and maybe the new ReadOnlyCollection

public struct MyStruct
{
    private readonly ReadOnlyCollection<int> _myInts;

    public MyStruct(ReadOnlyCollection<int> ints)
    {
        _myInts = ints;
    }
}
Chad Grant