Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is getting and setting a simple static properties thread safe? [duplicate]

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

like image 285
xsl Avatar asked Aug 19 '10 16:08

xsl


People also ask

Is static property thread-safe?

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.

Which of the following are 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.

What makes an object thread-safe?

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.

How do I ensure that my servlet is thread-safe explain with the program?

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).


2 Answers

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;
    }
}
like image 88
Jeffrey L Whitledge Avatar answered Sep 22 '22 04:09

Jeffrey L Whitledge


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.

like image 41
Jon Skeet Avatar answered Sep 20 '22 04:09

Jon Skeet