本文系作者原创,如需转载请注明出处!
https://zhuanlan.zhihu.com/p/23713957?refer=dreawer
一、概述
其实我是很讨厌写博客啥的,反而写笔记、总结会更有兴趣。刚开始我是拒绝的,不过既然已经开了头,那我就写个系列吧!设计模式,常用的就有23种,如下图(图片来自:终点)
是不是很缭乱?是的,我开始是懵逼的,现在还是懵逼状态。不过不要紧,我们虽然是菜鸟,但也是会终究成为大神的,我跟着大家一起学习进步。
这篇写的是23种设计模式中的一种——单例模式
1、什么是单例模式?
百度百科是这样定义的:单例模式是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例
我是这样理解的:单例模式就是只允许一个实例,最开始使用它的时候是C#中,我要实例化一个A窗体,但是有个需求就是A窗体必须是唯一,不管我在B窗体操作A窗体还是C窗体中操作A窗体都是如此,这时候就使用到了单例模式
2、单例模式分类
- A、懒汉单例模式:在第一次调用的时候实例化本身,在并发环境下,可能出现多个本身对象。所以线程是不安全的
- B、饿汉单例模式:在类初始化时,已经自行实例化一个静态对象,所以本身就是线程安全的
- C、登记单例模式:通过一个专门的类对各单例模式的单一实例进行管理和维护
3、特点
- A、 单例模式类只能有一个实例
- B、 单例模式类必须自己创建自己的唯一实例
- C、 单例模式类必须给所有其他对象提供这一实例
二、运用
1、懒汉单例模式
/**
* 描述:懒汉单例模式<p>
* 作者: kimball <p>
* E-mail: kimballlu@foxmail.com <p>
* 日期:2016-11-16 下午4:30:32 <p>
*/public class Singleton {
/**
* 该函数限制用户主动创建实例
*/
private Singleton() {}
private static Singleton singleton = null;
/**
* 获取Singleton实例(也叫静态工厂方法)
* @return Singleton
*/
public static Singleton getSingleton() {
/* 当singleton为空时创建它,反之直接返回,保证唯一性 */
if(singleton == null){
singleton = new Singleton();
}
return singleton;
}
}
线程安全的懒汉单例模式
在getSingleton()添加synchronized同步
/**
* 描述:懒汉单例模式,在getSingleton()方法添加同步<p>
* 作者: kimball <p>
* E-mail: kimballlu@foxmail.com <p>
* 日期:2016-11-16 下午4:30:32 <p>
*/
public class Singleton {
/**
* 该函数限制用户主动创建实例
*/
private Singleton() {}
private static Singleton singleton = null;
/**
* 获取Singleton实例,也叫静态工厂方法
* @return Singleton
*/
public static synchronized Singleton getSingleton(){
if(singleton==null){
singleton=new Singleton();
}
return singleton;
}
}
双重检查锁定
ps:已修正,仍不推荐使用,感谢@江南布衣指正
具体可参考正确使用双重检查锁定和双重检验锁失效”的问题说明
/**
* 描述:懒汉单例模式 ,双重检查锁定<p>
* 作者: kimball <p>
* E-mail: kimballlu@foxmail.com <p>
* 日期:2016-11-16 下午4:30:32 <p>
*/
public class Singleton {
/**
* 该函数限制用户主动创建实例
*/
private Singleton() {}
private volatile static Singleton singleton = null;
/**
* 获取Singleton实例,也叫静态工厂方法
* @return Singleton
*/
public static Singleton getInstance() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
静态内部类:静态内部类比双重检查锁定和在getInstance()方法上加同步都要好,实现了线程安全又避免了同步带来的性能影响
/**
* 描述:懒汉单例模式 ,静态内部类<p>
* 作者: kimball <p>
* E-mail: kimballlu@foxmail.com <p>
* 日期:2016-11-16 下午4:30:32 <p>
*/
public class Singleton {
/**
* 静态内部类
* @author kimball
*
*/
private static class LazyHolder {
// 创建Singleton实例
private static final Singleton INSTANCE = new Singleton();
}
/**
* 该函数限制用户主动创建实例
*/
private Singleton() {}
/**
* 获取Singleton实例,也叫静态工厂方法
* @return Singleton
*/
public static final Singleton getInstance() {
return LazyHolder.INSTANCE;
}
}
2、饿汉单例模式
/**
* 描述:饿汉单例模式<p>
* 作者: kimball <p>
* E-mail: kimballlu@foxmail.com <p>
* 日期:2016-11-16 下午4:30:32 <p>
*/
public class Singleton {
/**
* 该函数限制用户主动创建实例
*/
private Singleton() {}
private static final Singleton singleton = new Singleton();
/**
* 获取Singleton实例,也叫静态工厂方法
* @return Singleton
*/
public static Singleton getInstance() {
return singleton;
}
}
3、登记单利模式
/**
* 描述:登记单例模式<p>
* 作者: kimball <p>
* E-mail: kimballlu@foxmail.com <p>
* 日期:2016-11-16 下午4:30:32 <p>
*/
public class Singleton {
// 存储需要进行维护和管理的类的实例
private static Map<String, Singleton> map = new HashMap<String, Singleton>();
/**
* 静态创建实例并添加到Map集合
*/
static {
Singleton singleton = new Singleton();
map.put(singleton.getClass().getName(), singleton);
}
/**
* 该函数限制用户主动创建实例
*/
private Singleton() {};
/**
* 获取Singleton实例,也叫静态工厂方法
* @return Singleton
*/
public static Singleton getInstance(String name) {
/* 根据指定的类的名称从mao中获取实例并返回 */
return map.get(name);
}
// 一个示例性的商业方法
public String about() {
return "你好,我是RegSingleton";
}
public static void main(String[] args) {
Singleton singleton = Singleton.getInstance("com.Singleton");
System.out.println(singleton.about());
}
}
三、结语
以上就是单例设计模式,虽然单例设计模式是23种设计模式种比较简单的设计模式。但是三个臭皮匠也能顶一个诸葛亮,它自然有它存在的道理。
设计模式说白点就是编码的一种思维(之前在学校老师一个劲儿的说思维思维,现在我也开始说,手动滑稽)
我是以生活的角度去看待编码,编码就是世界的缩小版