设计模式之单列模式
单列模式:
概念:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
1、单列类只能有一个实列
SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。2、单列类必须自己创建自己的实列
3、单列类必须提供给所有其他对象获得该实列的方法
单列模式——饿汉式:
优点:线程安全、执行效率高
缺点:类加载时就初始化,浪费内存,容易产生垃圾对象(类加载时创建了对象,又没有调用方法获取实列)
/** * 单列模式——饿汉式 * @author ypf * */ public class Singleton1 { private static Singleton1 instance = new Singleton1(); //构造方法私有化 private Singleton1() { } public static Singleton1 getInstance() {return instance; } }
单列模式——懒汉式:
优点:第一次使用时才初始化,避免了内存浪费;
缺点:线程不安全,不支持多线程;
/** * 单列模式——懒汉式 * @author ypf * */ public class Singleton2 { private static Singleton2 instance; //构造方法私有化 private Singleton2() { } public static Singleton2 getInstance() { if(instance == null) { instance = new Singleton2(); } return instance; } }
单列模式——懒汉式(简单优化):
优点:实现了lazy-load(懒加载),第一次使用时才初始化,避免了内存浪费,线程安全;
缺点:执行效率低
/** * 单列模式——懒汉式(简单优化) * @author ypf * */ public class Singleton3 { private static Singleton3 instance; //构造方法私有化 private Singleton3() { }
//对方法加synchronized关键字 public synchronized static Singleton3 getInstance() { if(instance == null) { instance = new Singleton3();
}
return instance; } }
单列模式——双重检测锁式:
优点:第一次使用时才初始化,避免了内存浪费,线程安全,在多线程情况下也能保持高性能;
缺点 : 实现较复杂
在本次线程内,当读取一个变量时,为提高存取速度,编译器优化时有时会先把变量读取到一个寄存器中;以后再取变量值时,就直接从寄存器中取值;
/** * 单列模式——双重检测锁式 * @author ypf * */ public class Singleton4 { //给变量加volatile关键字,为了让编译器在使用这个变量时必须每次都重新读取这个变量的值,而不是使用保存在寄存器里的备份 private static volatile Singleton4 instance; //构造方法私有化 private Singleton4() { } public synchronized static Singleton4 getInstance() { //避免每次都获取锁 if(instance == null) { synchronized (Singleton4.class) { if(instance == null) { instance = new Singleton4(); } } } return instance; } }
单列模式——静态内部类式:
优点:线程安全、延迟加载、可以达到与双重检测锁一样的效果,但实现更简单,这种方式只适用于静态域的情况。
/** * 单列模式——静态内部类 * @author ypf * */ public class Singleton5 { private static class getSingleton{ private static final Singleton5 INSTANCE = new Singleton5(); } //构造方法私有化 private Singleton5() { } public static Singleton5 getInstance() { return getSingleton.INSTANCE; } }
单列模式——枚举式:
优点:避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,绝对防止多次实例化。
刚开始看到枚举式是这样的,
/** * 单列模式——枚举 * @author ypf * */ public enum Singleton6 { INSTANCE; public void anyMethod(){ } }
测试一下:
/** * 单列模式——枚举 * @author ypf * */ public enum Singleton6 { INSTANCE; private Singleton6() { System.out.println("构造方法"); } public void anyMethod(){ System.out.println(123); } }
测试代码:
public class TestSingleton { public static void main(String[] args) { Singleton6 instance = Singleton6.INSTANCE; Singleton6 instance1 = Singleton6.INSTANCE; Singleton6 instance2 = Singleton6.INSTANCE; Singleton6 instance3 = Singleton6.INSTANCE; System.out.println(instance.hashCode()); System.out.println(instance1.hashCode()); System.out.println(instance2.hashCode()); instance.anyMethod(); instance1.anyMethod(); instance2.anyMethod(); instance3.anyMethod(); } }
效果展示:
可以看到构造方法只执行了一次,即是同一个实列

更多精彩