在Java中,getInstance()方法是单例模式的核心,用于获取类的唯一实例。在多线程环境下,为了确保线程安全,我们需要对getInstance()方法进行同步处理。以下是几种处理并发的方法:
- 使用synchronized关键字:
public class Singleton { private static Singleton instance; private Singleton() { } public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
这种方法简单,但性能较差,因为在多线程环境下,每次调用getInstance()方法时都需要等待锁释放。
- 使用双重检查锁定(Double-Checked Locking):
public class Singleton { private static volatile Singleton instance; private Singleton() { } public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
这种方法在第一次检查时不需要获取锁,只有在实例为null时才需要获取锁并创建实例。这样可以提高性能,但仍然不是最佳实践。
- 使用内部静态类(Inner Static Class):
public class Singleton { private Singleton() { } private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.INSTANCE; } }
这种方法利用了Java类加载机制,保证了线程安全且性能较好。当getInstance()方法被调用时,内部静态类SingletonHolder才会被加载,从而创建唯一的实例。
- 使用枚举(Enum):
public enum Singleton { INSTANCE; // 添加其他方法 }
这种方法实现简单,且保证了线程安全和序列化安全。枚举类型的实例在类加载时被创建,确保了唯一性。同时,枚举类型天然支持序列化和反序列化,避免了反射攻击。
总之,处理并发的方法有很多,可以根据具体需求和场景选择合适的方法。在大多数情况下,使用内部静态类或枚举是最佳实践。