单例模式是一种常见的设计模式,主要确保一个类只有一个实例存在。
以下是几种常见的单例模式写法:
一、饿汉式
饿虎扑食般,在类加载时就创建单例对象。
public class SingletonHungry {
// 私有构造函数,防止外部创建实例
private SingletonHungry() {
}
// 静态私有成员,存储唯一实例
private static final SingletonHungry instance = new SingletonHungry();
// 公共静态方法,获取唯一实例
public static SingletonHungry getInstance() {
return instance;
}
}
这种写法简单直接,线程安全,但可能会造成资源浪费(如果实例在一开始并不被需要)。
二、懒汉式(线程不安全)
这种方式在第一次调用获取实例的方法时才创建单例对象。
public class SingletonLazy {
// 私有构造函数,防止外部创建实例
private SingletonLazy() {
}
// 静态私有成员,存储唯一实例
private static SingletonLazy instance;
// 公共静态方法,获取唯一实例
public static SingletonLazy getInstance() {
if (instance == null) {
instance = new SingletonLazy();
}
return instance;
}
}
这种写法在多线程环境下可能会出现多个实例的问题,因为多个线程可能同时进入创建实例的代码块。
三、懒汉式(线程安全,同步方法)
为了解决线程不安全的问题,可以使用同步方法来保证线程安全。
public class SingletonLazySafeSync {
// 私有构造函数,防止外部创建实例
private SingletonLazySafeSync() {
}
// 静态私有成员,存储唯一实例
private static SingletonLazySafeSync instance;
// 公共静态方法,获取唯一实例,同步方法保证线程安全
public static synchronized SingletonLazySafeSync getInstance() {
if (instance == null) {
instance = new SingletonLazySafeSync();
}
return instance;
}
}
这种写法虽然保证了线程安全,但每次获取实例都需要进行同步,效率较低。
四、懒汉式(线程安全,双重检查锁)
通过双重检查锁来优化同步方法的效率问题。
public class SingletonLazySafeDCL {
// 私有构造函数,防止外部创建实例
private SingletonLazySafeDCL() {
}
// 静态私有成员,存储唯一实例
private static SingletonLazySafeDCL instance;
// 公共静态方法,获取唯一实例
public static SingletonLazySafeDCL getInstance() {
if (instance == null) {
synchronized (SingletonLazySafeDCL.class) {
if (instance == null) {
instance = new SingletonLazySafeDCL();
}
}
}
return instance;
}
}
这种写法在保证线程安全的前提下,提高了效率,但在某些极端情况下可能会出现问题。
五、静态内部类方式
利用静态内部类来实现单例模式。
public class SingletonInnerClass {
// 私有构造函数,防止外部创建实例
private SingletonInnerClass() {
}
// 静态内部类,在类加载时创建单例实例
private static class SingletonHolder {
private static final SingletonInnerClass instance = new SingletonInnerClass();
}
// 公共静态方法,获取唯一实例
public static SingletonInnerClass getInstance() {
return SingletonHolder.instance;
}
}
这种写法既保证了线程安全,又能实现延迟加载,是一种比较推荐的写法。
以上就是几种常见的单例模式写法,每种写法都有其特点和适用场景,