Difference between volatile and transient in Java

1. Introduction

In Java, volatile and transient are two different keywords that serve distinct purposes. The volatile keyword is used to indicate that a variable's value will be modified by different threads. transient is used to indicate that a field should not be serialized — that is, not be saved as part of the object's state.

2. Key Points

1. volatile is used to make sure that the value of a variable is always read from the main memory and not from the thread's cache.

2. transient is used to prevent fields from being serialized during the serialization process.

3. Changes to a volatile variable are always visible to other threads.

4. transient variables are reset to the default value when an object is deserialized.

3. Differences

volatile transient
Ensures that the variable's value is read from and written to the main memory. Excludes a variable from the serialization process.
Useful in multithreading to get the latest updated value. Useful when you don't want to share sensitive data or when a field is not meaningful after deserialization.
No default value upon reading from memory. Fields are set to the default value upon deserialization (null for objects, zero for numeric types).

4. Example

import java.io.*;

// Example of volatile
class SharedObject {
    // The value of this variable will be read from the main memory every time.
    volatile int sharedCounter = 0;

    void increment() {

// Example of transient
class User implements Serializable {
    String name;
    transient String password; // This field will not be serialized

    User(String name, String password) {
        this.name = name;
        this.password = password;

public class Main {
    public static void main(String[] args) {
        SharedObject sharedObject = new SharedObject();

        User user = new User("JohnDoe", "s3cr3t");

        // Serialization
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("userInfo.ser"))) {
        } catch (IOException e) {

        // Deserialization
        try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream("userInfo.ser"))) {
            User deserializedUser = (User) ois.readObject();
            System.out.println("Name after deserialization: " + deserializedUser.name);
            System.out.println("Password after deserialization: " + deserializedUser.password);
        } catch (IOException | ClassNotFoundException e) {


Name after deserialization: JohnDoe
Password after deserialization: null


1. The sharedCounter variable is marked as volatile, which means any changes made to its value are reflected across threads.

2. The User class has a transient field password, which is not serialized. Upon deserialization, the password field is null because transient fields are not saved.

3. The main method demonstrates the serialization and deserialization process. The name is serialized and deserialized with its value intact, whereas password is not, due to it being marked as transient.

5. When to use?

- Use volatile when you need to ensure that multiple threads see the most up-to-date value for a variable.

- Use transient when you have fields that should not be part of the serialized state, such as sensitive information or fields that only make sense in the