Java单例模式的实现方法有以下几种:
- 懒汉式(Lazy Initialization): 在第一次使用时才创建实例。线程不安全版本的懒汉式实现如下:
public class Singleton { private static Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
可以通过在getInstance()
方法上加锁synchronized
来实现线程安全的懒汉式单例模式,但是会影响效率:
public class Singleton { private static Singleton instance; private Singleton(){} public static synchronized Singleton getInstance(){ if(instance == null){ instance = new Singleton(); } return instance; } }
- 饿汉式(Eager Initialization): 在类加载时就创建实例,线程安全。实现如下:
public class Singleton { private static Singleton instance = new Singleton(); private Singleton(){} public static Singleton getInstance(){ return instance; } }
由于在类加载时就创建实例,因此无法实现延迟加载。
- 双重检查锁定(Double Checked Locking): 在懒汉式的基础上,进行双重检查,确保线程安全且效率较高:
public class Singleton { private volatile static Singleton instance; private Singleton(){} public static Singleton getInstance(){ if(instance == null){ synchronized (Singleton.class){ if(instance == null){ instance = new Singleton(); } } } return instance; } }
使用volatile
修饰instance
变量可以保证多线程环境下的可见性和有序性。
- 静态内部类(Static Inner Class): 利用类的静态内部类来实现懒汉式的延迟加载和线程安全:
public class Singleton { private Singleton(){} private static class SingletonHolder{ private static final Singleton INSTANCE = new Singleton(); } public static Singleton getInstance(){ return SingletonHolder.INSTANCE; } }
静态内部类只有在第一次使用时才会被加载,从而实现了延迟加载。
- 枚举(Enum): 使用枚举类来实现单例模式,可以保证线程安全和防止反射攻击:
public enum Singleton { INSTANCE; public void doSomething(){ // do something } }