
BEST PRACTICES FOR MULTITHREADING IN
JAVA
This article lays down some of the best practices which you can use during your design or code reviews,
and assumes that you are familiar with the basics of mutithreading in java available
at articles/multithreading. I have learned many of these best practices from Effective Java by Joshua
Bloch, which tells how to use java to best effect.
Best Practices for Multithreading in Java
1. If you have shared mutable data, synchronize access to it. Synchronization makes sure that an
object is seen only in a consistent state by any thread, as it ensures mutual exclusion. It also
guarantees reliable communication between threads as it ensures that each thread entering a
synchronized region sees the effect of all previous modifications that were guarded by the same lock.
2. For reliable communication between threads, value written by one thread on a variable should be
visible to the other immediately. Even though reading or writing a variable other than log or double is
atomic, java doesn’t give a guarantee that a value written by one thread on a variable will be
visible to the other immediately, unless both read and write to it is guarded by synchronization or
the variable is a volatile variable.
3. Volatile variable guarantees that a value written by one thread will be visible to the other immediately,
but does not provide any mutual exclusion. Therefore, when you need only reliable communication by
making variables visible to other threads, but no mutual exclusion, use volatile, as it has slight
performance advantage over synchronization. However for compound statements like ‘myVar++’, you
should use synchronization or consider using atomic variables in java.util.concurrent.atomic package
like AtimicLong, which has a getAndIncrement() method, which is atomic.
4. Alternate approaches to synchronization are:
a. Share only immutable data.
b. Do not share at all.
c. Confine mutable data to a single thread.
d. Safely publish effectively mutable data. These are objects where one thread modifies the data for
sometime and then share it with other threads, so that synchronization is only required for the act of
sharing.
5. Inside a synchronized region, never call a method designed for inheritance or one provided by
client like a method of an object passed in, as these will allow client to take control and may result in
deadlock. We should use alien methods outside synchronized region.
6. Over use of synchronization should be avoided as it might result in deadlock, reduced performance
due to improper parallelization and even reduce JVM’s code optimization scope. You should do only very
less work as required inside synchronized regions. If a code can be moved outside a synchronized
region, it should be moved out.