How does clone (and why to avoid it) behave in multithreaded code?

The clone method in Java creates a copy of an object. However, its behavior can lead to complications in multithreaded environments. When an object is cloned, the state of the new object is identical to the original at the time of cloning, meaning that any references to mutable objects are also shared. This leads to potential race conditions where multiple threads manipulate shared mutable state, causing unexpected behavior.

Here is an example illustrating the potential issue:

class SharedObject { private int value; public SharedObject(int value) { this.value = value; } public int getValue() { return value; } public void setValue(int value) { this.value = value; } } class CloneExample implements Cloneable { private SharedObject sharedObject; public CloneExample(int value) { this.sharedObject = new SharedObject(value); } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } public SharedObject getSharedObject() { return sharedObject; } } // In a multithread environment public class Main { public static void main(String[] args) { CloneExample original = new CloneExample(1); CloneExample clone = (CloneExample) original.clone(); // Simulating multithreaded access new Thread(() -> original.getSharedObject().setValue(2)).start(); new Thread(() -> clone.getSharedObject().setValue(3)).start(); } }

clone multithreading Java race conditions object cloning shared mutable state