cyberconte
cyberconte

Reputation: 2398

What makes instance members thread-unsafe vs public static?

So we've all seen the Threading notification on MSDN for many available generic objects:

"Public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe."

My question is, what is it about being an instance variable vs a public static makes it unsafe?

Upvotes: 22

Views: 7814

Answers (5)

Sly Gryphon
Sly Gryphon

Reputation: 3785

TLDR; "Does this mean static methods are inherently thread safe? The answer is no. Classes with the above note will have thread safe static methods because the Microsoft engineers wrote the code in a thread safe manner, perhaps by using locks or other thread synchronization mechanisms" (quote taken from http://odetocode.com/Articles/314.aspx)

More detail

What is it? Nothing, except the code written for that particular class.

The statement is a declaration telling you that the programmers who wrote the class have made sure that all of the static members (methods and properties) are thread safe (but have not done so for instance members).

The have made sure statics are thread safe because, being static, it is very likely that they will be called by multiple threads, so they put in the extra work necessary to make sure this will be okay. Often static methods are also stateless functions, meaning they are already generally thread safe (no additional work needed).

In contrast, for instance members the statement is simply them telling you they have not been as careful with them.

Often instances will be created by a single thread and only accessed by that thread; if the instance is never accessed by multiple threads, then thread safety is not an issue, so the programmers didn't bother to add it.

The statement is not a claim about any inherent properties of static vs instance; both can be unsafe unless you put specific code in to ensure multiple threads can access them without problems (or if by nature they are already thread safe, e.g. a stateless function).

It is simply a statement that the programmers who wrote those classes have made sure that the static members are safe, but have not done so for instance members.

Upvotes: 0

Charles Bretana
Charles Bretana

Reputation: 146499

This is only true in general.

In general static methods are static because they are not dependant on nor do they access any instance defined data that another thread could also access. In general, the only variables they (a static method) utilizes are variables declared and tied to the static memory of the class the method is implemented in, not to the memory allocated for object -(the instance of the class) created for that object. A static method does not and cannot reference or utilize any such variable. If a method uses this kind of instance data variable, tied to a specific instance, it cannot be static. An Instance method, in contrast, does access some data element (property or field) of the instance.

If, otoh, a static method accesses a static property or field of the class, it is equally non-thread -safe.

There are four conditions needed for a race to be possible.

  1. The first condition is that there are memory locations that are accessible from more than one thread. Typically, these locations are global/static variables or are heap memory reachable from global/static variables.
  2. The second condition is that there is a property (often called an invariant), which is associated with these shared memory locations that must be true, or valid, for the program to function correctly. Typically, the property needs to hold true before an update occurs for the update to be correct.
  3. The third condition is that the invariant property does not hold during some part of the actual update. (It is transiently invalid or false during some portion of the processing).
  4. The fourth and final condition that must occur for a race to happen is that another thread accesses the memory while the invariant is broken, thereby causing inconsistent or incorrect behavior.

Upvotes: 17

Brian Rasmussen
Brian Rasmussen

Reputation: 116401

The problem with methods that are not thread safe is concurrent access to shared resources such as instance variables. If a static method only works on private/local data, it is inherently thread safe. However, there is no guarantee that static methods do that - this must be done explicitly.

Thus for a static method to be thread safe it cannot access static members without using synchronization and it should copy whatever data it receives as input before modifying it.

Upvotes: 0

Marc Gravell
Marc Gravell

Reputation: 1062780

Nothing inbuilt makes static any more-or-less different (re thread-safety) than instance, except:

  • static methods are often stateless "pure functional" methods, making them automatically thread-safe
  • there is a clear expectation on static members to be thread-safe (since you can't really control what each thread is doing at once) - so it is expected that any static method that could risk thread-safety be made thread-safe

This is not true for instance methods:

  • instance methods commonly access state on that instance
  • there is no expectation of thread safety unless it is made explicit in the documentation

So in general it is expected that the caller manage thread-safety over instances.

There are exceptions where instances are thread-safe (usually for things that are deeply tied to threading, such as a producer-consumer queue) - but IMO any static member that isn't thread safe is a bug.

Upvotes: 15

JaredPar
JaredPar

Reputation: 754715

It's the issue of state. What general makes methods unsafe for multiple threads is they do not access shared state in a thread safe manner. Static methods in general do not access shared state and hence are less likely to run into this problem. It's still possible to have race conditions in static / shared methods if they touch static data but in general static methods do not.

Upvotes: 8

Related Questions