软件设计模式-单件模式/单例模式
阅读数:101 评论数:0
跳转到新版页面分类
架构学
正文
一、概述
单件模式:确保一个类只有一个实例,并提供一个全局访问点。对于频繁使用的对象,特别是重量级对象,可以省略创建对象所花费的时间,同时降低GC压力。
采用私有构造器。Spring容器中的Bean默认为单例模式。
二、实现方式
1、线程安全-懒汉式(效率低)
因为每个执行getInstance都要同步,所以效率太低。
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
2、饿汉式
采用类加载机制避免多线程的同步问题,但没有达到lazy loading的效果。
// 第一种实现方式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
// 第二种实现方式
//这种方式和上面的实现方式一样,只是将静态成员变量放到了静态代码块中创建。
private static SingletonModeDemo1 MysingletonMode1 = null;
{
MysingletonMode1 = new SingletonModeDemo1();
}
public static SingletonModeDemo1 getInstance(){
return MysingletonMode1;
}
3、静态内部类(Holder)
同样基于类加载机制,但可以达到lazy loading的效果。
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
这种方式在很多框架上都很常见!
4、4双重校验锁。
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
这种方式即线程安全,又能够使性能不受到很大的影响。并不是每次进入getInstance方法都需要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进入下面的同步块,这是第一重检查。进入同步块后,再次检查实例是否存在,如果不存在,就是同步的情况下创建一个实例,这是第二重检查。
为什么加volatile关键字?
这是因为singleton=new Singleton();不是原子操作,添加volatile关键字后,编译器不会对指令重排。如果不加,存在线程1创建实例后(未完成初始化),线程2在判断对象是否为空时为假,返回了未初始化的对象。
相关推荐
设计原则:要依赖抽象,不要依赖具体类。
这个原则听起来很像是“针对接口编程,不针对实现编程”,然而这里更强调“抽象”,不能让高层组件依赖底层组件,而且,不管高层或低层组件,“两者”应该依赖于抽象。
一
一、概述
命令模式:将动作的请求者从动作的执行者中解耦。
发起请求的对象是调用者,调用者只要调用命令对象的execute()方法就可以让接收者工作,而不必知道具体的接收者对象是谁、是如何工作的。
命
模板方法模式:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
算法内的步骤不要切割的太细,否则会较没有弹性。
钩子是