《23天设计模式之单例模式》这是个人第二篇博客。在接下来的23天内,咱们将23种设计模式都去了解一下。今天咱们就来学习最简单的单例模式。java
在学习设计模式以前咱们不可避免要去想为何要学习这个东西,它是用来干吗的?算法
整体分为3大类:编程
public class Singleton { //静态单例 private static final Singleton INSTANCE = new Singleton(); //私有的构造方法 private Singleton(){}; // 获取单例的静态方法 public static Singleton getInstance() { return INSTANCE; } }
public class Singleton { //调用getInstance()方法时初始化 private static Singleton instance; //输出文字看这个构造方法被调用了几回 private Singleton(){ System.out.println(Thread.currentThread().getName() + "调用了构造方法"); }; //加了判空 public static Singleton getInstance(){ if (instance == null) { instance = new Singleton(); } return instance; } //使用多线程测试构造方法被调用了几回。正常来讲应该只调用一次。 public static void main(String[] args) { for (int i = 0; i < 4; i++) { new Thread(Singleton::getInstance).start(); } } } //输出以下: Thread-1调用了构造方法 Thread-2调用了构造方法 Thread-0调用了构造方法
分析:windows
public class Singleton { //volatile禁止指令重排优化 private static volatile Singleton instance; private Singleton(){ System.out.println(Thread.currentThread().getName() + "调用了构造方法"); }; //DCL双重检锁 public static Singleton getInstance(){ if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } public static void main(String[] args) { for (int i = 0; i < 4; i++) { new Thread(Singleton::getInstance).start(); } } } //输出: Thread-0调用了构造方法
分析:设计模式
不管执行多少次main函数,始终只有一条线程能调用构造函数。安全
指令重排:编译器、JVM 或者 CPU 都有可能出于优化等目的,对于实际指令执行的顺序进行调整。多线程
为何要禁止指令重排:多线程环境中线程交替执行,因为编译器指令重排的存在,两个线程使用的变量可否保证一致性是没法确认的,结果没法预测。函数
public class Singleton { private Singleton(){ }; public static Singleton getInstance() { return InnerClass.INSTANCE; } //静态内部类 public static class InnerClass { private static final Singleton INSTANCE = new Singleton(); } }
public enum Singleton { INSTANCE; public Singleton getInstance(){ return INSTANCE; } }
以上就是单例模式的主要内容。接下来咱们了解如下单例模式的常见应用场景。oop
Windows的Task Manager(任务管理器)就是很典型的单例模式学习
windows的Recycle Bin(回收站)就是典型的单例应用。在整个系统运行过程当中,回收站一直维护着仅有的一个实例。
网站的计数器,通常也是采用单例模式实现,不然难以同步。
多线程的线程池的设计通常也是采用单例模式,这是因为线程池要方便对池中的线程进行控制。
感谢您花时间阅读个人博客,以上就是我对单例模式的一些理解,如有不对之处,还望指正,期待与您交流。
本篇博文系原创,仅用于我的学习,转载请注明出处。