饿汉式 懒汉式
饿汉式
class Singleton {
private static Singleton instance=new Singleton();
private Singleton(){}
static Singleton getInstance() {
return instance;
}
}
懒汉式
class Singleton {
private static Singleton instance=null;
private Singleton(){}
static Singleton getInstance() {
if(instance==null)
instance=new Singleton();
return instance;
}
}
单例模式是软件设计模式中的一种,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。这种模式在系统资源管理、线程同步等方面有广泛应用,例如数据库连接池、缓存管理和日志服务等。
我们来看"饿汉式"的实现方式。饿汉式单例在类加载时就完成了实例化,因此它具有线程安全的特性。在给出的代码中,Singleton类的静态成员变量`instance`在类加载时就被初始化为一个新的Singleton实例。这种方式确保了无论有多少个线程尝试访问getInstance()方法,`instance`始终是已经创建好的实例。由于实例化操作在类加载时已完成,所以饿汉式单例模式的性能较好,但同时也意味着即使应用没有使用到Singleton实例,它也会被创建并占用内存。
接着,我们分析"懒汉式"的实现。懒汉式单例的特点是在首次调用getInstance()方法时才进行实例化,因此也称为延迟加载。如代码所示,当第一次调用getInstance()时,会检查`instance`是否为null,如果是,则创建一个新的Singleton实例。这种方式在一定程度上节省了资源,因为只有在真正需要时才会创建实例。然而,原始的懒汉式单例并不线程安全,如果多个线程同时进入getInstance()方法的if语句块,可能会创建多个Singleton实例,违背了单例模式的设计原则。为了解决这个问题,通常会采用双重检查锁定(Double-Check Locking)或静态内部类等方式来实现线程安全的懒汉式单例。
双重检查锁定的懒汉式单例代码如下:
```java
class Singleton {
private volatile static Singleton instance = null;
private Singleton() {}
static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
```
这里使用了volatile关键字保证多线程环境下对instance的可见性和有序性,避免了指令重排序的问题,同时使用synchronized关键字保证了线程安全,确保只有一个线程能创建实例。
另外,静态内部类的方式也能实现线程安全的懒汉式单例,因为Java类加载机制保证了类的加载是线程安全的:
```java
class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton() {}
static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
```
在这个实现中,SingletonHolder类只会在Singleton类被加载时才被加载,因此INSTANCE的初始化也是线程安全的,同时延迟了Singleton实例的创建。
总结来说,单例模式通过限制类的实例化次数,提供了全局唯一的访问点,有多种实现方式,如饿汉式、懒汉式、双重检查锁定和静态内部类等。每种方式都有其优缺点,开发者应根据实际需求选择合适的实现策略。