Reputation: 148524
I read some articles and did some testings/investigating and I think there's NOT accurate conculsion (due to incorrect wording maybe )
Ok . few investigations :
There was this guy who asked this question :
Why are static fields generally considered threadsafe?
Well , all of the repliers said : No. they are not.
Eric also said :
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.
(this is pretty close to my claim which i'll ask here later)
But I also found here that Hans said :
And oh boy — this other guy said :
Re-entrancy is still a problem, though. static is not thread-safe, and even static readonly is not re-entrant-safe.
Ok , i'm confused.
p.s. I'm not talking about this kind of situation :
public class A
{
public static List<int> LST = new List<int>();
}
List<>
is not thread safe so I don't care who holds it. BUT ->
Let's look at this
public class A
{
public static int Five=5;
}
What is not thread safe about this code ?
I can't see how Five
could not always be 5 :
As far as I know - Five
could never be 0
( initial value) and it would always be five no matter how many threads are accessing it !
NOW , I DO AGREE that If I was writing a code which USES this Five
field , then I'd have to watch out for changed value !
Example :
if (Five < array.Length) return array[five]; //can throw an IndexOutOfBoundsException if five is modified
With this - I Agree !
But (imho) it is incorrect to say ( as a rule) that static fields are not thread safe !
Their usage has to be treated as if it could change via another thread.
(Also, obviously - Static fields which reference a non-threadsafe object like List<>
- surely not going to be thread safe)
What i'm trying to say here is that static fields are not thread safe for specific scenarios , and not as a rule !
Question :
Can someone please shed light ? I'm sure I miss something here ( or am I not ? ) is it true that static fields are not always non-thread safe ( as a rule)
And what about this readonly
which makes static field threadsafe (all it does it make it one time initialize without reassigned ) ? does it make it thread safe or does it not ? (and what about re-entrent ?)
Upvotes: 2
Views: 904
Reputation: 73452
is it true that static fields are not always non-thread safe?
static
shouldn't be in the argument itself. static
has nothing to do with thread safety. It just allows the field to be the part of "Type" itself rather than "Instance".
what about this readonly which makes static field threadsafe ? does it make it thread safe or does it not ?
Answer depends on what do you meant by thread safe? Thread safe is more general term in which everybody has their own meaning, If you can be more precise in what do you mean by thread safe, It will be easy to answer.
Upvotes: 2
Reputation: 8502
Readyonly static fields can only be initialized at either declare time or in the static constructor and not afterwards. So, they can't be changed by none other that the static constructor which is called only once when first static field or method of that class is accessed. Static fields (not readonly) are not threadsafe on their own because multiple threads can still access them and change them to produce race conditions.
If you are not changing any state in a class, then there is no question of making it thread safe. Thread safety is done to make modifying the fields avoid race conditions and keep their value consistent across the threads.
Please run below example in Console to check the output to see the field five
is not Thread-safe.
public class CheckThreadSafety
{
private static int five = 5;
public static void Increment(int iVal)
{
five += iVal;
}
public static int CurrentFiveValue { get { return five; } }
}
public class Program
{
public static void Main()
{
for (var i=0; i<10000; i++)
{ var t = i;
Task.Factory.StartNew ( () =>
{
CheckThreadSafety.Increment(t);
Console.WriteLine("Five Value should be : " + (t + 5).ToString() + ", and is: " + CheckThreadSafety.CurrentFiveValue);
} );
}
}
}
Moreover, if you change
five
field in above code to be public, then callers have to ensure it's thread-safety.
Another example using Singleton
, Read more here:
-Below code is not thread-safe:
using System;
public class Singleton
{
private static Singleton instance;
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
instance = new Singleton();
}
return instance;
}
}
}
-But, below code due to readonly is thread-safe:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton() { }
public static Singleton Instance
{
get
{
return instance;
}
}
}
Upvotes: 1
Reputation: 51214
So the question is, do you really need to expose your code to all the potential problems? Having a public static
field in your app makes it temptingly simply to change it from an arbitrary piece of code and create threading problems.
Or, you can decide that all callers must take a lock before working with the field, where the lock object is also a public static
field. So, you are delegating the thread-safety concern to the callers of that class, and relying on nothing more than conventions to keep your code safe. Why, when there are better ways to achieve it? What about deadlocks?
As you've said yourself:
Their usage has to be treated as if it could change via another thread.
It am pretty sure this implies that you are actually aware they are inherently not thread safe.
Upvotes: 1
Reputation: 68660
public class A
{
public static int Five=5;
}
This example is not thread-safe in the sense that if two threads execute return ++Five;
, both threads might end up returning 6
, instead of returning 6 and then 7. There's a race condition.
That's why Hans says read-only fields are inherently thread-safe (kinda). What he forgot to mention is that the field's type should also be immutable (which int
is). A field that can only be read, and never changed in any way, is thread-safe.
What i'm trying to say here is that static fields are not thread safe for specific scenarios , and not as a rule !
Yes, being static has nothing to do with thread-safety. Thread-safety depends on:
Upvotes: 2
Reputation: 29
A static variable, doesn't mean it's "constant", it just means that it was statically allocated at compile time, rather than dynamically at run-time.
If you set the static variable before starting any threads, and then never, ever, change it again, but only read from it, then, by the nature of the logic in your code, you are never putting yourself in a situation in which you will be exposed to the problems associated with non-thread safe code. That is not the same as saying that static variables are thread safe.
Pre-emptive threading is called that because a thread switch can cause code execution to pre-empt the execution of another thread, even in mid-write, or mid-read. In other words, consider that your static variable is an integer, which depending on the architecture, could be 4 bytes, or 8 bytes. Unless the variable is specifically declared atomic, one thread could start reading the memory, but say it only manages to read the first 2 bytes before another thread pre-empts it and writes to the same variable. When the first thread resumes, it reads the remaining bytes, which of course, by now, is inconsistent.
Upvotes: 1
Reputation: 62093
It does make it threadsafe - but that is a feature of readonly, not static. Variables that can not change value are per definition not something that can have a change in one thread while read in another thread, by the virtue of.... missing the change to start with.
Generally anything that is read only is per definition thread safe. It is only with changes in values that you start getting into trouble.
Upvotes: 1