《23天设计模式之单例模式》这是我的第二篇博客。在接下来的23天内,我们将23种设计模式都去了解一下。今天我们就来学习最简单的单例模式。
在学习设计模式之前我们不可避免要去想为什么要学习这个东西,它是用来干嘛的?
总体分为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调用了构造方法
分析:
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;
}
}
以上就是单例模式的主要内容。接下来我们了解以下单例模式的常见应用场景。
Windows的Task Manager(任务管理器)就是很典型的单例模式
windows的Recycle Bin(回收站)就是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。
网站的计数器,一般也是采用单例模式实现,否则难以同步。
多线程的线程池的设计一般也是采用单例模式,这是由于线程池要方便对池中的线程进行控制。
感谢您花时间阅读我的博客,以上就是我对单例模式的一些理解,若有不对之处,还望指正,期待与您交流。
本篇博文系原创,仅用于个人学习,转载请注明出处。
原文:https://www.cnblogs.com/guying-blog/p/14655537.html