C#:What If a Static Method Is Called from Multiple Threads

C# : What if a static method is called from multiple threads?

Variables declared inside methods (with the possible exception of "captured" variables) are isolated, so you won't get any inherent problems; however, if your static method accesses any shared state, all bets are off.

Examples of shared-state would be:

  • static fields
  • objects accessed from a common cache (non-serialized)
  • data obtained via the input parameters (and state on those objects), if it is possible that multiple threads are touching the same object(s)

If you have shared state, you must either:

  • take care not to mutate the state once it can be shared (better: use immutable objects to represent state, and take a snapshot of the state into a local variable - i.e. rather than reference whatever.SomeData repeatedly, you read whatever.SomeData once into a local variable, and then just use the variable - note that this only helps for immutable state!)
  • synchronize access to the data (all threads must synchronize) - either mutually exclusive or (more granular) reader/writer

Calling static method via Multiple threads - Can they meddle with each other's Input Parameters

The short answer to your question is no, as long as you pass in different List instances across all your different threads. .NET handles threading fine, and in itself won't get itself into a tangle, it's only if your code encourages it to do so can things get messy.

The way things get mixed up is by sharing state across different threads. So as an example, having a static method you may think it a good idea to use a static variable somewhere:

private static int count;

public static void MyMethod() {
count = count + 1;
if(count == 5) {
console.log("Equal to 5");
}
};

This sort of method is not thread safe because count can be modified by two different threads at the same time. In fact it's possible that count could be incremented to 5, and then another thread increment it to 6 before the if check, therefore you'd never log anything - which would obviously be a bit confusing.

The other way you can share state, is if you pass something in, hence my caveat at the start of the answer. If you pass the same object into the method from multiple threads this object should ideally be immutable so in your case a collection that can't be modified. This prevents the internals of the method modifying the object that could impact another thread. As already mentioned though, this is only a concern if you pass the same instances in, within different threads.

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

Accessing a static method from different threads

No, they do not have to wait. Both threads can enter Foo at the same time and in the code above each thread will sleep for 2 minutes.

The only way to make one thread wait on another is to add a synchronization / locking mechanism like the lock keyword, or tyes Mutex or Monitor (to name a few).

How does static code run with multiple threads?

Yes, the method should be able to run fine in multiple threads. The only thing you should worry about is accessing the same file in multiple threads at the same time.

C# - Are Parameters Thread Safe in a Static Method?

The parameters are, in this case, two immutable values. Within a method, only a single thread is operating on the set of parameters, as multiple threads calling the method will each have their own stack and execution context, which means each thread has their own independent set of parameters and local variables, so no other thread can impact those variables.

As such, this is completely thread safe in relation to those two variables.

Note that, parameters passed by ref are not necessarily thread safe, as that would potentially allow a single variable to be shared among two or more threads, which would require synchronization.

Also, if you pass a reference type instance that isn't immutable (ie: a custom class) as a parameter, the internal state of that class would need synchronization, as it could potentially be used by more than one thread. The reference itself would be thread safe, as it's passed as a copy (unless passed using ref).

What happens when two threads call the same static method at the same time?

It depends on whether your method changes outside state.

static long i = 0l;
public static String someMethod(){
String accm = "";
for(;i < Integer.MAX_VALUE*20/*Just to make sure word tearing occurs*/; i++)
accm += i
return accm;
}

Will cause problems:

  • Longs are not guaranteed to be set atomically, so they might be 'torn' (Spec)
  • ++ is not an atomic operation. It is exactly the same as {int n = i; i = i + 1; return n}
    • i = i + 1 is also not atomic, if it changes in the middle, some values will be repeated
    • The return of n might be stale

But if i is a local variable, there will be no problems. As long as any outside state is guaranteed to be immutable while it is being read, there can never be any problems.

Calling Static method in multi-threading

There is nothing in here that would cause another thread to be used; why would it? your code:

  • creates an instance of Test
  • invokes (callvirt) Print on that instance
    • which takes a Monitor lock around itself (not a good idea, btw)
    • sleeps for 10 seconds
    • writes a line to the console
    • releases the Monitor lock
  • invokes (call) the static Something method
    • which writes a line to the console

No extra threads required. I should emphasize: it would work identically with regards to threads even if you didn't release the Monitor lock (by using Monitor.Enter without a Monitor.Exit); again: lock does not create threads.

A lock simply stops (blocks) other threads from locking the same object for the duration - it creates a mutually exclusive region. It doesn't create threads.



Related Topics



Leave a reply



Submit