Some rules of thumb:
(1) Keep an eye on the context when your declare a variable
- Write to class attributes
(static) has to be synchronized
- Write to instance attributes has to be synchronized
- Keep all variables as local as possible (do not put them in a member
context unless it makes sense)
- Mark variables that are read only immutable
(2) Lock the access to mutable class or instance attributes: Variables that are part of the same invariant should be protected by the same lock.
(3) Avoid Double Checked Locking
(4) Keep locks when you run a distributed operation (call subroutines).
(5) Avoid busy waiting
(6) Keep the workload low in synchronized sections
(7) Do not allow to take a client control while you are in a synchronized block.
(8) Comments! This really helps to understand what the other guy had in mind with declaring this section synchronized or that variable immutable.