To avoid data corruption in multithreaded Java programs, one has to protect the data that is shared between multiple threads as described in detail in CON30-J. Synchronize access to shared mutable variables. This can be done at the object level by using synchronized
blocks (coarse-grained locking), as a result locking out other threads from interfering. If synchronization is used judiciously, (See CON00-J. Use synchronization judiciouslyDo not invoke a superclass method or constructor from a synchronized region in the subclass) deadlocks do not usually crop up.
...