单列模式:

概念:保证一个类仅有一个实例,并提供一个访问它的全局访问点。

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(); } }

 

效果展示:

 设计模式之单列模式 随笔

 

可以看到构造方法只执行了一次,即是同一个实列

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄