一、概述
单例模式是一种创建型设计模式,目的是为了保证在某个应用程序中,某个类有且只有一个实例,并提供公共的对外访问入口。目前常用的单例模式的实现主要有8种方式,接下来让我们一起来分析一下。
二、分类
1. 饿汉式
(1) 静态变量
public class BadmashStaticConstantSingleton {
private static BadmashStaticConstantSingleton instance = new BadmashStaticConstantSingleton();
private BadmashStaticConstantSingleton() {
}
public static BadmashStaticConstantSingleton getInstance() {
return instance;
}
}
(2) 静态代码块
public class BadmashStaticCodeSingleton {
private static BadmashStaticCodeSingleton instance;
static {
instance = new BadmashStaticCodeSingleton();
}
private BadmashStaticCodeSingleton() {}
public static BadmashStaticCodeSingleton getInstance() {
return instance;
}
}
优点:静态变量或者是静态代码块在类的初始化的时候完成了实例化,引用存储在方法区或者堆中(JDK版本),对象存储在堆中。实现起来比较简单,也保证了线程安全。
缺点:不是懒加载,若未使用该实例,将会造成额外的内存开销。
2. 懒汉式
(1) 普通方式
public class IdlerSingleton {
private static IdlerSingleton instance;
private IdlerSingleton() {
}
public static IdlerSingleton getInstance() {
if (instance == null) {
instance = new IdlerSingleton();
}
return instance;
}
}
缺点:实现了懒加载,但是线程不安全。在多线程的情况下,条件判断与创还能对象,会导致创建多个对象。
(2) 同步方法
public class IdlerSyncMethodSingleton {
private static IdlerSyncMethodSingleton instance;
private IdlerSyncMethodSingleton() {
}
public static synchronized IdlerSyncMethodSingleton getInstance() {
if (instance == null) {
instance = new IdlerSyncMethodSingleton();
}
return instance;
}
}
优点:实现了懒加载,保证了线程安全
缺点:效率低。一个线程获取到锁后,执行方法,其他线程等待,待获取到锁后再执行方法。
(3) 同步代码块
public class IdlerSyncCodeSingleton {
private static IdlerSyncCodeSingleton instance;
private IdlerSyncCodeSingleton() {
}
public static IdlerSyncCodeSingleton getInstance() {
if (instance == null) {
synchronized (IdlerSyncCodeSingleton.class) {
instance = new IdlerSyncCodeSingleton();
}
}
return instance;
}
}
优点:实现了懒加载,效率高于同步方法。
缺点:线程不安全。在条件判断时,可能会出现多个线程满足条件。虽然创建对象是线程安全的,但也会出现创建多个对象的情况。
(4) 双重检查
public class IdlerDoubleCheckSingleton {
private static volatile IdlerDoubleCheckSingleton instance;
private IdlerDoubleCheckSingleton() {
}
public static IdlerDoubleCheckSingleton getInstance() {
if (instance == null) {
synchronized (IdlerDoubleCheckSingleton.class) {
if (instance == null) {
instance = new IdlerDoubleCheckSingleton();
}
}
}
return instance;
}
}
优点:实现了懒加载,效率高(同步代码块只在第一次创建对象时执行),线程安全。
注:实例需使用volatile修饰,防止指令重排序。
3. 静态内部类
public class InnerStaticClassSingleton {
private InnerStaticClassSingleton() {
}
public static InnerStaticClassSingleton getInstance() {
return InnerClass.INSTANCE;
}
private static class InnerClass {
private static final InnerStaticClassSingleton INSTANCE = new InnerStaticClassSingleton();
}
}
优点:实现了延迟加载,JVM类加载机制 和 初始化阶段的线程安全性保证了线程安全。
4. 枚举
public class EnumSingleton {
private EnumSingleton() {
}
public static EnumSingleton getInstance() {
return Singleton.INSTANCE.getInstance();
}
private enum Singleton {
INSTANCE;
private EnumSingleton instance;
Singleton() {
instance = new EnumSingleton();
}
public EnumSingleton getInstance() {
return instance;
}
}
}
优点:实现简单,JVM 禁止反射创建枚举实例,从而保证了安全性。
缺点:不支持延迟加载,类加载过程中已被实例化了。