Possible Duplicate:
Are C# auto-implemented static properties thread-safe?
In the following example class
static class Shared
{
public static string[] Values { get; set; }
}
many reader threads read the Values
string array periodically, while from time to time a single writer will replace the whole array with a new value using the setter. Do I need to use a ReaderWriterLock
or is this something C# will handle automatically?
Edit: In my case the only required "thread safety" is: Nothing bad should happen when the writer replaces the array while the reader is searching for a value. I don't care if the readers will use the new value immediately as long as they will use it in the future
Thread SafetyStatic variables are not thread safe. Instance variables do not require thread synchronization unless shared among threads. But, static variables are always shared by all the threads in the process. Hence, access to static variable is not thread safe.
A thread-safe class is a class that guarantees the internal state of the class as well as returned values from methods, are correct while invoked concurrently from multiple threads. The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.
To put it simply, a class instance is immutable when its internal state can't be modified after it has been constructed. A MessageService object is effectively immutable since its state can't change after its construction. So, it's thread-safe.
To make a servlet or a block within a servlet thread-safe, do one of the following: Synchronize write access to all instance variables, as in public synchronized void method() (whole method) or synchronized(this) {...} (block only).
This use is thread safe:
string[] localValues = Shared.Values;
for (int index = 0; index < localValues.length; index++)
ProcessValues(localValues[index]);
This use is not thread safe, and can result in out-of-bounds exceptions:
for (int index = 0; index < Shared.Values.Length; index++)
ProcessValues(Shared.Values[index]);
I would prefer to make thread safe calls more natural by doing something like this:
static class Shared
{
private static string[] values;
public static string[] GetValues() { return values; }
public static void SetValues(string[] values) { Shared.values = values; }
}
Of course, the users can still put GetValues() in the loops, and it would be just as bad, but at least it's obviously bad.
Depending on the situation, an even better solution might be to hand out copies, so that the calling code can't mutate the array at all. This is what I would usually do, but it may not be appropriate in your situation.
static class Shared
{
private static string[] values;
public static string[] GetValues()
{
string[] currentValues = values;
if (currentValues != null)
return (string[])currentValues.Clone();
else
return null;
}
public static void SetValues(string[] values)
{
Shared.values = values;
}
}
Without any extra protection, there's no guarantee that a reading thread will ever see the new value. In practice, as long as the reading thread is doing anything significant, it will see the new value. In particular, you'll never see "half" an update, with a reference pointing to dead space.
If you make the field volatile
, I believe even this danger is removed - but lock-free programming is generally hard to reason about. This means abandoning it being an automatically-implemented property, of course.
If 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