1.作用
在一个服务中对象是唯一,只能是一个,就像是古代的皇帝
2.基本定义
a.私有构造器
b.自行实例化对象
c.对外开放的获取此对象的方法
3.看模式代码
public class Emperor {
//防止产生多个对象
private Emperor(){}
//内部实例化
private static Emperor emperor = new Emperor();
//对外提供获取次对象的方法
public static Emperor getInstance(){
return emperor;
}
}
4.优点
a.由于单例模式创建的对象在内存中只有你个内存,可以减少内存开销,尤其对频繁创建、销毁,而且内容不会变的方法
b.单例模式可以设置全局访问点,优化和共享资源的访问,例如可以设置API名单,数据库名单
c.单例模式可以避免对资源的多重占用,例如写文件,单例实例可以避免对资源的同时写
4缺点
扩展难,因为单例模式是自行实例化的
5使用场景
a.要求一个类有且仅有一个对象
b.要求生成唯一唯一序列号的环境
c.整个项目需要共享访问点和共享资源
d.创建一个对象需要消耗大量资源时,如io连接、数据库连接
6常用的几种单例模式写法
a.饿汉模式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){
}
public static Singleton getInstance() {
return instance;
}
}
这种方式在类加载时就完成了初始化,所以类加载较慢,但获取对象的速度快。 这种方式基于类加载机制避免了多线程的同步问题,但是也不能确定有其他的方式(或者其他的静态方法)导致类装载,这时候初始化instance显然没有达到懒加载的效果
b.懒汉模式(线程不安全)
/**
* 不用:会出现线程不安全
*
*/
public class One {
private One(){}
private static One one = null;
public static One getInstance(){
if (Objects.isNull(one)){
return new One();
}
return one;
}
}
c.懒汉模式(线程安全)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
这种写法能够在多线程中很好的工作,但是每次调用getInstance方法时都需要进行同步,造成不必要的同步开销,而且大部分时候我们是用不到同步的,而且会发生锁被占用的情况,所以不建议用这种模式
d.双重检查模式 (DCL)
import java.util.Objects;
/**
* double check 模式,会出现小概率的失效问题
*/
public class Three {
private Three(){}
private volatile static Three three = null;
public static Three getInstance(){
if (Objects.isNull(three)){
synchronized (Three.class){
if (Objects.isNull(three)){
return new Three();
}
}
}
return three;
}
}
e.静态内部类单例模式
/**
* 静态内部类单例模式
*/
public class Four {
private Four(){}
public static Four getInstance(){
return FourHolder.FOUR;
}
private static class FourHolder{
private static final Four FOUR = new Four();
}
}
第一次初始化Four类是不会创建对象,只有在调用getInstance()方法时才会创建对象,这样既保证了懒也保证了线程安全,所以推荐使用此方式
注意:
以上创建方式都会有一个问题,就是在反序列时会重写创建对象,需要加一下代码来防止此问题:
private Object readResolve() {
return singleton;
}
感谢:
https://blog.csdn.net/itachi85/article/details/50510124
http://www.hollischuang.com/archives/1144
代码:
https://github.com/sleepxdq/java-design-patterns-zh
网友评论