Basically, however, I separate methods in terms of concurrency into:
- Stateless method
Any method that does not try to modify any shared state. This ensures parallel calls to this method from multiple threads remain parallel. This is regardless of the method ownership, whether it is bound to a class-instance (object) or to a class (static), or even to an enum. I enjoy immutable programming (to extreme points) so this is naturally my first choice.
- Stateful method
This type of method normally deals with object locking, objects that serve as states and are shared among callers. Without locking, state is indeterminate, and thus renders the purpose of state sharing useless. Execution of this method, therefore, is bound to be sequential to the order the state lock is acquired and released. With locking, this falls into a synchronized method (below). Otherwise it is just not the best practice.
- Synchronized method
An overly generalized category for this type of method execution, but anyway.
A method, whether wholly synchronized or having a synchronized statement, is bound to be sequentially invoked to the order its lock is acquired and released. It is not possible for two invocations of synchronized methods on the same object to interleave [Synchronized Methods]. A regular method made synchronized will mean it is bound to its owning object instance. In the case of a static synchronized method, the thread acquires the lock for the class object associated with the class, simulating the same behaviour as class instance-bound methods.