Java
Volatile keyword
Synchronized keyword
Java programming
Multithreading

Difference between volatile and synchronized in Java

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In Java, managing consistent state changes across multiple threads is a critical aspect when it comes to building reliable applications. Two common mechanisms provided for managing state in a multi-threaded environment are volatile and synchronized. These are crucial in ensuring thread safety but they serve different purposes and operate in different ways.

Understanding the volatile Keyword

The volatile keyword in Java is used to indicate that a variable's value will be modified by different threads. Variables declared as volatile do not use the cache where threads might keep their own copy of the variable, which can lead to inconsistent data being observed by different threads. Instead, volatile variables are always read from and written to the main memory. This means that changes made by one thread to a volatile variable are visible to all other threads immediately.

A simple example can illustrate this:

java
1public class Counter {
2    private volatile int count = 0;
3    
4    public void increment() {
5        count++;
6    }
7    
8    public int getCount() {
9        return count;
10    }
11}

Here, any thread accessing count either through increment() or getCount() is seeing the most recent write to count from any thread.

Understanding synchronized

While volatile ensures visibility of changes across threads, synchronized in Java is used to control access to a particular block of code or object by multiple threads. When a method or block of code is marked with the synchronized keyword, only one thread can enter the corresponding block or method on that instance. Other threads attempting to enter the locked code are blocked until the first thread exits the block.

Here's how it might be used:

java
1public class SynchronizedCounter {
2    private int count = 0;
3    
4    public synchronized void increment() {
5        count++;
6    }
7    
8    public synchronized int getCount() {
9        return count;
10    }
11}

In this example, the synchronized keyword ensures that when one thread is executing increment() or getCount(), no other thread can enter these methods for the same instance.

Key Differences

The primary difference between volatile and synchronized lies in their purpose - volatile is about visibility (ensuring that changes to a variable are consistently reflected across threads), while synchronized is about atomicity (ensuring that a sequence of operations within a block is executed by only one thread at a time).

Moreover, volatile is generally less expensive than synchronized in terms of performance. Using synchronized involves locking which can be a relatively heavy operation and can lead to thread contention, wherein multiple threads are waiting to acquire the lock.

Table Summarizing Differences Between volatile and synchronized

Featurevolatilesynchronized
PurposeEnsures visibility of variable changes across threadsEnsures atomicity of a block of operations
Method/BlockOnly applicable to variablesApplicable to methods and blocks
PerformanceGenerally faster and less overheadHeavier, can lead to thread contention
Locking MechanismNo locking involvedInvolves locking and can block threads

Additional Considerations

While volatile can be a solution for visibility issues, it does not resolve all concurrency problems. For instance, the increment operation (count++) in the volatile example is not atomic, which means using volatile alone might not be sufficient for actions that need to be atomic.

Combining these tools appropriately depending on the context – visibility or atomicity – is crucial for writing correct, efficient, multi-threaded Java applications. Experts typically recommend using synchronized carefully to avoid significant performance impacts and considering higher-level concurrency controls like java.util.concurrent package features, which offer more sophisticated mechanisms for handling synchronization and coordination between threads.


Course illustration
Course illustration

All Rights Reserved.