写在前面:
视频是什么东西,有看文档精彩吗?
视频是什么东西,有看文档速度快吗?
视频是什么东西,有看文档效率高吗?
1. 概述
诸小亮:你听说过设计模式吗?
张小飞:听说过,但是不太清楚具体是什么
诸小亮:设计模式——是一种解决问题的通用方案,是前辈们对解决某些问题的一些经验总结
张小飞:有什么好处?
诸小亮:可以提高代码重用性、健壮性,让代码更容易被他人理解
张小飞:明白了,我们要讲设计模式吗?
诸小亮:是的,目前 java 中比较流行的有23种设计模式
张小飞:这么多?
诸小亮:不过,我们今天只讲——单例模式
2. 单例模式
张小飞:什么是单例模式?
诸小亮:单例模式——确保一个类只能创建一个对象
张小飞:只能创建一个对象?能做到吗?
诸小亮:想要实现也很简单,只需满足两点
1. 类的外部不能通过 new 关键字创建对象,所以构造方法应该是 private
2. 在这个类中自己 new 一个对象,并且提供 get 方法,让外部可以获取
张小飞:能提供一下代码吗?
诸小亮:当然可以,看下面的代码
class Single{
//1. 私有的构造方法,外部不能使用,但是本类中可以使用
private Single(){
}
//2. 搞一个静态变量,这样类初始化时候,instance就已经有值了
//设置为private,是避免外部修改这个变量,当然也可以使用final
private static Single instance = new Single();
//3. 对外提供获取对象的方式,这样每次调用这个方法拿到的都是同一个对象
public static Single getInstance(){
return instance;
}
}
张小飞:原来是这样子,那么想使用 Single 对象,就只能调用 getInstance 方法了
诸小亮:是的,这就是传说中的饿汉式
张小飞:哦?为什么这么说?
诸小亮:因为它在别人使用之前就把对象给创建好了
张小飞:原来如此,这么说还有其他方式?
诸小亮:还有一个懒汉式,在调用 getInstance 时才创建对象
class Single{
//1. 私有的构造方法,外部不能使用,但是本类中可以使用
private Single(){
}
//2. 搞一个静态变量
private static Single instance = null;
//3. 对外提供获取对象的方式
public static Single getInstance(){
//如果 instance 是空的时候,在创建对象,这就是懒汉式
if(instance == null){
synchronized (Single.class){
if(instance == null){
instance = new Single();
}
}
}
return instance;
}
//方法中用了两次if判断,这就是经典的双检锁
}
诸小亮:你能解释一下,为什么用了两次 if 判断吗?
张小飞:这个。。。,让我看一会
五分钟后。
张小飞:我明白为什么用两次 if 判断了
诸小亮:哦?那你来说说
张小飞:原因很简答,这样可以保证多线程下 Single 对象不会被多次创建
- 第一次 if 判断,比较简单,就不解释了
- 多线程环境下,是有可能多个线程同时执行到 synchronized (Single.class) 这句代码的
- 但是只有一个线程能进入 synchronized 代码块
- 如果 synchronized 代码块中不使用 if 判断,就会导致 Single 对象被多次创建
诸小亮:嗯嗯,不错,不错
张小飞:不过,单机模式在上面场景下可以用到呢?
诸小亮:当多个线程需要操作同一个对象时
- 比如:程序A 修改后,程序B 需要拿到对象中的最新数据继续操作