Reputation: 67293
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.
Upvotes: 8
Views: 8717
Reputation:
i is thread safe syntactically. But when you assign instance variable's values,instance method return value to i, then the shared data is manipulated by multiple threads.
Upvotes: 1
Reputation: 11243
i is a local variable so it's not shared state.
If your getFromDb() is reading from, say, an oracle sequence or a sql server autoincrement field then the db is taking care of synchronization (in most scenarios, excluding replication/distributed DBs) so you can probably safely return the result to any calling thread. That is, the DB is guaranteeing that every getFromDB() call will get a different value.
Thread-safety is usually a little bit of work - changing the type of a variable will rarely get you thread safety since it depends on how your threads will access the data. You can save yourself some headache by reworking your algorithm so that it uses a queue that all consumers synchronize against instead of trying to orchestrate a series of locks/monitors. Or better yet make the algorithm lock-free if possible.
Upvotes: 1
Reputation: 8553
i will be "thread safe" as each thread will have it's own copy of i on the stack as you suggest. The real question will be are the contents of getFromDb() thread safe?
Upvotes: 1
Reputation: 11320
While your int i is thread safe, your whole case is case is probably not thread safe. Your int i is, as you said, thread safe because each thread has its own stack trace and therefore each thread has his own i. However, your thread all share the same database, therefore your database accesses are not thread safe. You need to properly synchronize your database accesses to make sure that each thread will see the database only at the correct moment.
As usual with concurrency and multithreading, you do not need to synchronize on your DB if you only read information. You do need to synchronize as soon as two thread will try to read/write the same set of informations from your DB.
Upvotes: 1
Reputation: 1064324
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).
Upvotes: 34
Reputation: 100057
As long as the variable is local to the method it is thread-safe. If it was a static variable, then it wouldn't be by default.
class Example
{
static int var1; //not thread-safe
public void Method1()
{ int var2; //thread-safe
}
}
Upvotes: 3
Reputation: 44347
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.
Upvotes: 5