您的位置:首页 > 其它

【设计模式 4】怎样写出更高逼格的单例模式

2017-01-13 21:15 337 查看
导读:话说姑娘我一直想着分个总结设计模式来着,一直没把这个派上日程,现在看一本书,里面提到了一些设计模式,现在就总结总结。话说我之前写单例模式,一直都是按照大话设计模式上的那种写法,也就是传统的加锁,加2把锁的这种方式,今天看了看人家说性能优化,利用内部类,写出了更高逼格的代码,佩服之余,总结一番。



一、两种常见写法分析

1.1,单锁懒汉式

public class Singleton {
private static Singleton instance=null;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}


分析:1,给静态成员变量instance初始值赋值null,确保系统启动时没有额外的负载;2,虽然保证了线程安全,但是在多线程环境下,由于引入了Synchronized同步关键字,增加了系统消耗

1.2,流行的双重检查机制

public class Singleton {
private volatile static Singleton singleton=null;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}


分析:1,增加了volatile关键字,使得singleton变量不得被重排读写顺序,始终共享内存(不怎么明白的,可以去看看我的博客:【java基础 14】锁的粒度:ThreadLocal、volatile、Atomic和Synchronized
2,改变了同步的范围,缩小了锁的粒度! 但由于volatile关键字,会影响JVM本身的必要代码优化



二、逼格比较高的两种写法

2.1,使用内部类

public class StaticSingleton{
private static class SingletonHolder{
private static StaticSingleton instance=new StaticSingleton();
}

public static StaticSingleton getInstance(){
return SingletonHolder.instance;
}
}


分析:通过使用内部类,当StaticSingleton被加载时,其内部类不会被初始化,也就是说,当StaticSingleon类被载入JVM时,不会初始化单例类,只有当getInstance方法被调用时,才会加载SingletonHolder类,初始化instance。实例的建立是在类加载时完成,所以天生对多线程友好,不用使用关键字,节省消耗!

2.2,避免串行创建多个实例

public class SerSingleton implements java.io.Serializable{
String name;

private SerSingleton(){
name="SerSingleton";
}

private static SerSingleton instance=new SerSingleton();
public static SerSingleton getInstance(){
return instance;
}

private Object readResolve(){
return instance;//阻止生成新的实例,总是返回当前对象
}
}
分析:序列化操作提供了一个很特别的钩子(hook)-类中具有一个私有的被实例化的方法readresolve(),这个方法可以确保类的开发人员在序列化将会返回怎样的object上具有发言权。在实现了readResolve()方法后,readObject()方法形同虚设,直接使用readResolve()替换了原本的返回值,从而在形式上构造了单例

三、总结

由于自己在基础上的不牢固,很多时候写代码都不严谨高效,比如这次的单例模式,就想着线程安全,然后也没有想着性能怎么样的问题。就跟LinkList和ArrayList一样,到哪儿都用ArrayList,额。。。。。遇到一个,总结一个,下次写单例,就不再写Synchronized这种形式的咯!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: