饿汉单例
懒汉单例
代码实现
饿汉
EagerSingleton
类的构造方法被声明为私有,以防止外部通过 new
关键字实例化该类。而类中定义了一个私有静态变量 instance
,它在类加载的时候就被创建并初始化为 EagerSingleton
类的一个实例。
getInstance()
方法是获取单例对象的静态方法,它直接返回了已经创建好的 instance
对象。
由于饿汉单例在类加载的时候就创建了对象,因此它具有线程安全的特性,但可能会造成一定的资源浪费,因为无论是否使用该单例对象,都会被提前创建。
懒汉单锁
懒汉双重检测
在上面的代码中,LazySingleton
类的构造方法被声明为私有,以防止外部通过 new
关键字实例化该类。类中定义了一个私有静态变量 instance
,它在第一次调用 getInstance()
方法时才会被创建并初始化为 LazySingleton
类的一个实例。
getInstance()
方法是获取单例对象的静态方法。在方法中,首先检查 instance
是否为空,如果为空则进入同步代码块。在同步代码块内部,再次检查 instance
是否为空,这是为了防止多个线程同时通过了第一个检查而进入同步块,从而创建多个实例。如果 instance
仍然为空,则创建新的实例并将其赋值给 instance
。
使用 volatile
关键字修饰 instance
变量可以保证变量的可见性,从而避免在多线程环境下出现问题。
懒汉双重检测通过双重检查和同步块的方式实现了延迟加载和线程安全,同时也提高了性能。因此,它是一种常见的单例模式实现方式。
IODH
实现懒汉模式
在上面的代码中,LazySingleton
类内部定义了一个私有静态内部类 SingletonHolder
。在 SingletonHolder
内部,定义了一个私有静态变量 instance
,它是 LazySingleton
类的一个实例。
由于静态内部类 SingletonHolder
只有在 getInstance()
方法被调用时才会被加载,所以在类加载的过程中并不会创建 instance
对象。只有当第一次调用 getInstance()
方法时,SingletonHolder
类会被加载,从而创建并初始化 instance
对象。这种方式利用了 Java
类加载的线程安全性和延迟加载的特性,实现了懒汉模式。
因此,通过 IODH
实现懒汉模式,可以在需要时延迟创建单例对象,并且保证了线程安全性。
单例模式总结
单例模式作为一种目标明确、结构简单、理解容易的设计模式,在软件开发中使用频率相当高,在很多应用软件和框架中都得以广泛应用。