C# multi-threading: Acquire read lock necessary?

The short answer is: it depends.

The long answer is:

  • If it is not a shared value, i.e, only one thread can see it (or use it), you don’t need any synchronization.

  • If it is an immutable value, i.e., you set it only once and then only ever read, it is safe to do so without synchronization (as long as you don’t start reading before the first write completes).

  • If it is a “primitive” type of at most 32-bits (e.g. byte, short, int) you can get stale (old) data when reading. If that doesn’t bother you, you’re set. If stale data is undesirable, making the variable volatile can fix this problem without additional synchronization for reads. But if you have racing writers, you will need to follow the same advice as for longs below.

  • If it is a “primitive” type longer than 32-bits (e.g. long, decimal, double) you need synchronization, otherwise you could read “half” of one value, “half” of another, and get crazy results. For this the recommended approach is to use the methods in the Interlocked class, for both reads and writes..

  • If it is a reference type, you will need synchronization to avoid seeing an invalid state (Jeff Lamb’s picture example is a good one). The lock statement might be enough for that. Again, you need to lock for both reads and writes.

There are some other points to consider (how long to lock, for example), but I think these are enough to answer your question.

Leave a Comment