一 . 模式动机
- 在某些情况下,我们只需要一个对象实列,例如,window系统的任务管理器,你不论打开多少次,它都是同一个管理器对象,还有时间,系统系需要一个时间对象就够用。
- 因此,我们就可以用单例模式来,设计一个类只能创建一个实例,无论你怎么搞,都只会是那一个实例。
二 . 模式定义
- 单例模式(Singleton Pattern):单例模式确保一个类只有一个实例,并且自行实例化并向整个系统提供这个实例。
三 . 模式结构
(图片来源于网络)
- Singleton:单例类
四 . 模式分析
- 这个模式非常简单,只有一个类。
- 单例模式有三个要点:一个类只能由一个实例;必须自行创建这个实例;必须自行向系统提供这个实例
- 单例模式有一个私有构造函数,确保用户无法直接new它,这个模式有要有一个***静态私有的成员变量***instance,还要有一个***静态工厂方法***getintance()负责检验是否已经存在,如果已经有一个实例,则返回已有实例,若没有则创建一个实例,并且存入instance
五 . 实例代码
- Singleton:单例类
public class Single {
private static Single instance;//私有静态成员变量
//将构造器私有,让别人无法直接new这个类
private Single(){
}
//公有静态工厂方法,确保这个类只有一个实例
public static Single getinstance(){
if (instance==null) {
instance = new Single();
return instance;
}else return instance;
}
}
- 测试类
public class Client {
public static void main(String[] args) {
Single single = Single.getinstance();
Single single1 = Single.getinstance();
System.out.println(single==single1);
}
}
- 测试结果
E:\Java\jdk1.8.0_171\bin\java.exe "-javaagent:E:\idea\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=63079:E:\idea\IntelliJ IDEA 2019.1.3\bin" -Dfile.encoding=UTF-8 -classpath "E:\Java\jdk1.8.0_171\jre\lib\charsets.jar;E:\Java\jdk1.8.0_171\jre\lib\deploy.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\access-bridge-64.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\cldrdata.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\dnsns.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\jaccess.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\jfxrt.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\localedata.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\nashorn.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\sunec.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\sunjce_provider.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\sunmscapi.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\sunpkcs11.jar;E:\Java\jdk1.8.0_171\jre\lib\ext\zipfs.jar;E:\Java\jdk1.8.0_171\jre\lib\javaws.jar;E:\Java\jdk1.8.0_171\jre\lib\jce.jar;E:\Java\jdk1.8.0_171\jre\lib\jfr.jar;E:\Java\jdk1.8.0_171\jre\lib\jfxswt.jar;E:\Java\jdk1.8.0_171\jre\lib\jsse.jar;E:\Java\jdk1.8.0_171\jre\lib\management-agent.jar;E:\Java\jdk1.8.0_171\jre\lib\plugin.jar;E:\Java\jdk1.8.0_171\jre\lib\resources.jar;E:\Java\jdk1.8.0_171\jre\lib\rt.jar;E:\Design pattern\out\production\Design pattern" Singleton单例模式.Client
true
Process finished with exit code 0
六 . 模式优缺点
-
优点
- 提供唯一一个实例的受控访问
- 节约系统资源
-
缺点
- 单例模式没有抽象层,所以扩展有很大的困难
- 单例职责过重,违背“单一职责原理”
七 . 模式适用环境
- 系统只需要一个实例对象
八 . 模式应用例子
- java.lang.Runtime
public class Runtime{
//静态私有成员变量
private static Runtime currentRuntime = new Runtime();
//私有构造器
private Runtime() {}
//静态公有工厂方法
public static Runtime getRuntime() {
return currentRuntime;
}
......
}
- 数据库的主键编码生成器
九 . 模式扩展
- 饿汉式单例和懒汉式模式,若静态私有成员变量在声明时就赋值则为饿汉,为空是懒汉式
//饿汉式
private static Singleton instance = new Singleton();
//懒汉式
private static Singleton instance = null;
- 两者比较
- 饿汉式单例在类加载时就将自己实列化,比较浪费系统资源,单速度比懒汉式单例类快。
- 懒汉式单例类要处理好多个线程同时首次引用此类时的访问限制问题。