Thread Safety of Method Calls on "Shared" Static Constant Property

Are static methods thread safe

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. (I can't think of any .NET BCL static methods which aren't thread-safe.) Instance methods are often not thread-safe because the typical pattern is to create an object and use it repeatedly from one thread, and if it does have to be used from multiple threads, the co-ordination involved includes making sure that the object is used safely. In very many cases that's more appropriate to do in the co-ordinating code than in the object itself. (Usually you want to make whole sequences of operations effectively atomic - something which can't be done within the object.)

Your Timer class is most definitely not thread-safe: two threads can stomp on each other's data with ease, and there's nothing to stop a thread from using "stale" data when calculating the duration.

Use the Stopwatch class instead - that's what it's there for. Admittedly if you want to use one instance from multiple threads you'll need to take the normal steps to ensure safety, but you'll be in a much better position in general. Admittedly Stopwatch is far from perfect too - see this question and the comment below for more details - but it is at least what the type is designed for. (Who knows, it may be fixed some time...)

ThreadSafety and static fields - confusion?

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.

Is calling a static method from an instance method thread safe?

Yes this is thread-safe. Threading issues generally occur around sharing resources, which you're not doing here. This is following the Microsoft threading suggestions:

Avoid providing static methods that alter static state. In common
server scenarios, static state is shared across requests, which means
multiple threads can execute that code at the same time. This opens up
the possibility for threading bugs. Consider using a design pattern
that encapsulates data into instances that are not shared across
requests.

If you were to use a static variable somewhere in these functions, then no it wouldn't be thread safe unless you started putting locking or other thread safe ways of handling that variable.

Are static variables shared between threads?

There isn't anything special about static variables when it comes to visibility. If they are accessible any thread can get at them, so you're more likely to see concurrency problems because they're more exposed.

There is a visibility issue imposed by the JVM's memory model. Here's an article talking about the memory model and how writes become visible to threads. You can't count on changes one thread makes becoming visible to other threads in a timely manner (actually the JVM has no obligation to make those changes visible to you at all, in any time frame), unless you establish a happens-before relationship.

Here's a quote from that link (supplied in the comment by Jed Wesley-Smith):

Chapter 17 of the Java Language Specification defines the happens-before relation on memory operations such as reads and writes of shared variables. The results of a write by one thread are guaranteed to be visible to a read by another thread only if the write operation happens-before the read operation. The synchronized and volatile constructs, as well as the Thread.start() and Thread.join() methods, can form happens-before relationships. In particular:

  • Each action in a thread happens-before every action in that thread that comes later in the program's order.

  • An unlock (synchronized block or method exit) of a monitor happens-before every subsequent lock (synchronized block or method entry) of that same monitor. And because the happens-before relation is transitive, all actions of a thread prior to unlocking happen-before all actions subsequent to any thread locking that monitor.

  • A write to a volatile field happens-before every subsequent read of that same field. Writes and reads of volatile fields have similar memory consistency effects as entering and exiting monitors, but do not entail mutual exclusion locking.

  • A call to start on a thread happens-before any action in the started thread.

  • All actions in a thread happen-before any other thread successfully returns from a join on that thread.

Is my C# static method in a non static class thread safe?

If your static method does not change any member variables, and does not call mutating methods on its parameters, it is re-entrant, and is, therefore, thread-safe.

Static methods that perform mutating operations on their parameters may not be thread-safe when concurrent threads invoke the method with the same object as its parameter.

For example, if your method mutates o1 through methods, properties, or public variables, the method would no longer be thread-safe.

What Makes a Method Thread-safe? What are the rules?

If a method (instance or static) only references variables scoped within that method then it is thread safe because each thread has its own stack:

In this instance, multiple threads could call ThreadSafeMethod concurrently without issue.

public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number; // each thread will have its own variable for number.
number = parameter1.Length;
return number;
}
}

This is also true if the method calls other class method which only reference locally scoped variables:

public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number;
number = this.GetLength(parameter1);
return number;
}

private int GetLength(string value)
{
int length = value.Length;
return length;
}
}

If a method accesses any (object state) properties or fields (instance or static) then you need to use locks to ensure that the values are not modified by a different thread:

public class Thing
{
private string someValue; // all threads will read and write to this same field value

public int NonThreadSafeMethod(string parameter1)
{
this.someValue = parameter1;

int number;

// Since access to someValue is not synchronised by the class, a separate thread
// could have changed its value between this thread setting its value at the start
// of the method and this line reading its value.
number = this.someValue.Length;
return number;
}
}

You should be aware that any parameters passed in to the method which are not either a struct or immutable could be mutated by another thread outside the scope of the method.

To ensure proper concurrency you need to use locking.

for further information see lock statement C# reference and ReadWriterLockSlim.

lock is mostly useful for providing one at a time functionality,

ReadWriterLockSlim is useful if you need multiple readers and single writers.

How to make static method thread safe?

Question 1: For my second method CommonFunction2, do I use a new
static lock i.e. LockObjCommonFunction2 in this example or can I reuse
the same lock object LockObj defined at the begining of the function.

If you want to synchronize these two methods, then you need to use the same lock for them. Example, if thread1 is accessing your Method1, and thread2 is accessing your Method2 and you want them to not concurrently access both insides, use the same lock. But, if you just want to restrict concurrent access to just either Method1 or 2, use different locks.

Question 2: Is there anything which might lead to threading related
issues or can I improve the code to be safe thread.

Always remember that shared resources (eg. static variables, files) are not thread-safe since they are easily accessed by all threads, thus you need to apply any kind of synchronization (via locks, signals, mutex, etc).

Quesiton 3: Can there be any issues in passing common class instead of
struct.. in this example SendMailParameters( which i make use of
wrapping up all parameters, instead of having multiple parameters to
the SendMail function)?

As long as you apply proper synchronizations, it would be thread-safe. For structs, look at this as a reference.

Bottomline is that you need to apply correct synchronizations for anything that in a shared memory. Also you should always take note of the scope the thread you are spawning and the state of the variables each method is using. Do they change the state or just depend on the internal state of the variable? Does the thread always create an object, although it's static/shared? If yes, then it should be thread-safe. Otherwise, if it just reuses that certain shared resource, then you should apply proper synchronization. And most of all, even without a shared resource, deadlocks could still happen, so remember the basic rules in C# to avoid deadlocks. P.S. thanks to Euphoric for sharing Eric Lippert's article.

But be careful with your synchronizations. As much as possible, limit their scopes to only where the shared resource is being modified. Because it could result to inconvenient bottlenecks to your application where performance will be greatly affected.

    static readonly object _lock = new object();
static SomeClass sc = new SomeClass();
static void workerMethod()
{
//assuming this method is called by multiple threads

longProcessingMethod();

modifySharedResource(sc);
}

static void modifySharedResource(SomeClass sc)
{
//do something
lock (_lock)
{
//where sc is modified
}
}

static void longProcessingMethod()
{
//a long process
}


Related Topics



Leave a reply



Submit