2

I'm a .NET and Java developer who is relatively new to threading. I'd like to know why static fields, static constructors, etc are generally considered "threadsafe".

For example, when constructing a singleton in .NET, one of the tricks to make it threadsafe is to make some of the components of the pattern static.

Please let me know if any of my above assumptions are incorrect.

MedicineMan
  • 15,008
  • 32
  • 101
  • 146
  • 12
    Where did you read that making something static makes it threadsafe? – Oliver Charlesworth Jan 25 '12 at 00:06
  • Somewhat related post http://stackoverflow.com/q/1090650/758280. – Jeffrey Jan 25 '12 at 00:07
  • i don't know about C# and .net but in java static fields are not threadsafer than any other type of field. – yurib Jan 25 '12 at 00:08
  • From Jeffrey's link: `Static methods aren't inherently thread-safe. They're treated no differently by the CLR than instance methods. The difference is that one should generally try to make them thread-safe` – L.B Jan 25 '12 at 00:08
  • 6
    You have it backwards. **Because static fields and methods are likely to be accessed from multiple threads, it is a good programming practice to do the work to ensure that they are threadsafe.** That's why you see so much documentation that says "the static methods of this class are threadsafe, the rest are not". – Eric Lippert Jan 25 '12 at 02:11

4 Answers4

11

I think you are getting confused, those 'tricks' are not about threading, but avoiding initialization by threads. So if something is initilized when the app loads, you don't have to worry about threads having to intialize things when they first ask for the resource, and hence avoid the race condition of which thread gets there first

Keith Nicholas
  • 43,549
  • 15
  • 93
  • 156
3

Your above assumptions are incorrect. A static field is no more threadsafe than any other field.

Even in creating a singleton, the flag/pointer/item that indicates the object has already been built has to be protected by a synchronisation primitive if there's a possibility it may be called by multiple threads simultaneously.

The reason you use a static (class-level) variable for singletons is because you only want one object of the class. Using an object-level variable would restrict you to one object per object rather than one object per class, and one object per object is, well, just a regular object :-)

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
1

Static constructors are (mostly) thread-safe because the runtime takes a lock before running them, thereby providing synchronization. Re-entrancy is still a problem, though.

As far as "static fields generally considered threadsafe", I can only offer that the general wisdom comes from a handful of idiots who got teaching jobs because they couldn't get a job as a professional developer, and now passed on that idiocy to a bunch of students who never had a chance to learn better.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • What's not thread safe with `class fff { public static readonly int five = 5; }` ? – Royi Namir May 21 '14 at 20:12
  • @Royi: That's more threadsafe because it is `readonly`, not because it is `static`. (But see my comments to Chris's answer, even your example is not perfectly threadsafe) – Ben Voigt May 21 '14 at 20:13
  • Removing the readonly would make it not thread safe ? Are you talking about that one thread can see the default value before initialization ? – Royi Namir May 21 '14 at 20:15
  • @RoyiNamir: No, I'm talking about having a data race where one thread changes the value at the same time that another thread writes to it. For example `if (five < array.Length) return array[five];` can throw an `IndexOutOfBoundsException` if `five` is modified. – Ben Voigt May 21 '14 at 20:16
  • This is method code which should be protected via lock . I asked about merely field with value – Royi Namir May 21 '14 at 20:19
  • @Royi: `static` is not thread-safe, and even `static readonly` is not re-entrant-safe. I've already explained why. – Ben Voigt May 21 '14 at 20:21
1

Static fields are not inherently thread safe- this is a fallacy. Static has nothing to do with threading really. It just means that the field is associated with a type, and not an instance of a type. The only thing to note about thread safety with regard to statics is that they are commonly set by a static constructor, and are commonly readonly e.g.:

class Foo {
    // You can safely read `five` from any thread
    public static readonly  int five = 5; 
}

This does not make the object itself threadsafe in any way however. there is nothing threadsafe about this collection:

class Foo {
    // You still need to take a lock before writing to this list and probably while reading from it
    public static readonly List<Int> myList = new List<Int>; 
}
Chris Shain
  • 50,833
  • 6
  • 93
  • 125
  • Well, even `readonly` on a field of value type doesn't guarantee thread safety. – Ben Voigt Jan 25 '12 at 00:12
  • No- just means that once it is set no one else is going to write to it, so you can't get a "dirty read" on it – Chris Shain Jan 25 '12 at 00:13
  • Sure you can. If the constructor starts a thread, or stores `this` somewhere another thread can read it, and then assigns the field. – Ben Voigt Jan 25 '12 at 00:15
  • I'm not sure I follow- what is `this` in your example? This is a static – Chris Shain Jan 25 '12 at 00:17
  • For static `readonly` values, the problem is re-entrancy (as I mentioned in my answer). I just didn't want someone to think that instead of using `static` to magically cure threading woes they would use `readonly` instead. – Ben Voigt Jan 25 '12 at 00:20