Make the constructor `private`
Declare a `private static` instance of the class
Provide a `public static` method to return the instance
Use lazy initialization if you want to create the instance only when needed
Use eager initialization if you want to create the instance at class loading time
Synchronize the access method if lazy initialization must be thread-safe
Use double-checked locking with `volatile` for better thread-safe lazy initialization
Use the Initialization-on-demand holder idiom for thread-safe lazy loading
Implement `readResolve()` to preserve singleton property during serialization
Prevent cloning by overriding `clone()` and throwing `CloneNotSupportedException`
Keep the class `final` if you do not want it to be subclassed
