serialization
it is the process of converting an object’s state into a byte stream, which can be saved to a file, sent over a network or stored in a database.
transient modifier
- The
transientmodifier is used to indicate that a field should not be serialized when an object is converted to a byte stream - When an object is serialized, transient fields are excluded from the serialized data and are typically initialized to their default values (e.g., null for objects, 0 for numbers) when deserialized.
import java.io.*;
class User implements Serializable {
String name;
transient String password; // This field won't be serialized
public User(String name, String password) {
this.name = name;
this.password = password;
}
}
public class Main {
public static void main(String[] args) throws Exception {
User user = new User("Alice", "secret123");
// Serialize
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("user.ser"));
oos.writeObject(user);
oos.close();
// Deserialize
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("user.ser"));
User deserializedUser = (User) ois.readObject();
ois.close();
System.out.println("Name: " + deserializedUser.name); // Output: Alice
System.out.println("Password: " + deserializedUser.password); // Output: null
}
}
volatile
- The volatile modifier ensures that a field’s value is always read from and written to the main memory, preventing thread-local caching.
- It guarantees visibility of changes to a variable across multiple threads and prevents certain compiler optimizations that could reorder instructions.
- Ensures visibility: When one thread modifies a volatile variable, the change is immediately visible to all other threads.
- Prevents reordering: The compiler and JVM won’t reorder operations on a volatile variable in a way that breaks its visibility guarantees.
- Does not provide atomicity (e.g., i++ is not thread-safe even if i is volatile).
class SharedResource {
volatile boolean flag = false;
public void toggleFlag() {
flag = true; // Write to main memory
}
public boolean isFlag() {
return flag; // Read from main memory
}
}
public class Main {
public static void main(String[] args) {
SharedResource resource = new SharedResource();
// Thread 1: Modifies flag
new Thread(() -> {
try {
Thread.sleep(1000);
resource.toggleFlag();
System.out.println("Flag set to true");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
// Thread 2: Reads flag
new Thread(() -> {
while (!resource.isFlag()) {
// Busy wait
}
System.out.println("Flag is now true");
}).start();
}
}
| Feature | transient | volatile |
|---|---|---|
| Purpose | Controls serialization | Ensures thread visibility |
| Applied To | Instance fields | Instance or static fields |
| Context | Serialization (I/O) | Multithreading |
| Effect | Excludes field from serialization | Ensures reads/writes go to main memory |
| Thread Safety | Not related to threads | Provides visibility, not atomicity |