Note that it's not that a method has a call stack - a thread has a call stack. Methods are invoked by a thread.
Unless the method is inlined, invoking it may push parameters onto the call stack, but will definitely push the return address onto the call stack.
Each thread call stack is independent of the call stack of any other thread. If only the stack is accessed, then the method is thread-safe.
Other storage could be accessed to make the method not thread-safe. That includes static data and instance data as well as objects referenced by them. A static method has no access to instance data, which makes it easier for it to be thread-safe. You only need to watch out for access to static data, or objects referenced by static data:
private static int _balance;
private static void ThreadSafetyIssues()
{
// Not thread safe
int temp = _balance;
temp ++;
_balance = temp;
// Not thread safe
temp = (int) HttpContext.Current.Session["balance"];
temp ++;
HttpContext.Current.Session["balance"] = temp;
}
The HttpContext.Current
property is static. This means that any thread can access the context at the same time, including Session
. This is just as non-thread-safe as the simple static _balance
field above.