Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread safety and local variables

Tags:

c#

If I have a local variable like so:

Increment()
{
    int i = getFromDb(); // get count for a customer from db 
};

And this is an instance class which gets incremented (each time a customer - an instance object - makes a purchase), is this variable thread safe? I hear that local variables are thread safe because each thread gets its own stack, etc etc.

Also, am I right in thinking that this variable is shared state? What I'm lacking in the thinking dept is that this variable will be working with different customer objects (e.g. John, Paul, etc) so is thread safe but this is flawed thinking and a bit of inexperience in concurrent programming. This sounds very naive, but then I don't have a lot of experience in concurrent coding like I do in general, synchronous coding.

EDIT: Also, the function call getFromDb() isn't part of the question and I don't expect anyone to guess on its thread safety as it's just a call to indicate the value is assigned from a function which gets data from the db. :)

EDIT 2: Also, getFromDb's thread safety is guaranteed as it only performs read operations.

like image 318
GurdeepS Avatar asked Mar 24 '09 22:03

GurdeepS


People also ask

Are local variables in static method thread-safe?

Local variables are stored in each thread's own stack. That means that local variables are never shared between threads. That also means that all local primitive variables are thread safe.

Are local variables shared between threads?

Tip: Unlike class and instance field variables, threads cannot share local variables and parameters. The reason: Local variables and parameters allocate on a thread's method-call stack. As a result, each thread receives its own copy of those variables.

Are private variables thread-safe?

Ans. Yes for sure, you are creating 101 logical threads (1 main thread + 100 other by calling start() method of thread).


2 Answers

i is declared as a local (method) variable, so it only normally exists in the stack-frame of Increment() - so yes, i is thread safe... (although I can't comment on getFromDb).

except if:

  • Increment is an iterator block (i.e. uses yield return or yield break)
  • i is used in an anonymous method ( delegate { i = i + 1;} ) or lambda (foo => {i=i+foo;}

In the above two scenarios, there are some cases when it can be exposed outside the stack. But I doubt you are doing either.

Note that fields (variables on the class) are not thread-safe, as they are trivially exposed to other threads. This is even more noticeable with static fields, since all threads automatically share the same field (except for thread-static fields).

like image 179
Marc Gravell Avatar answered Sep 29 '22 15:09

Marc Gravell


Your statement has two separate parts - a function call, and an assignment.

The assignment is thread safe, because the variable is local. Every different invocation of this method will get its own version of the local variable, each stored in a different stack frame in a different place in memory.

The call to getFromDb() may or may not be threadsafe - depending on its implementation.

like image 43
Bevan Avatar answered Sep 29 '22 14:09

Bevan