您的位置:首页 > 其它

单例模式

2016-06-02 21:57 288 查看
单例模式

简单的可以理解在系统中只存在一个实例对象

适用场合:

一个对象需要频繁创建和销毁

  对象创建需要消耗一定的资源

一个对象即可满足需要

单例模式优点: 节约内存,提高性能,避免了大对象频繁创建的消耗

单例模式缺点:   不符合开闭原则,该类不支持拓展,当功能变化时修改代码是必然的

单例的几种实现方式: 

1、 饿汉式 

public class Sington {

public static Sington sington = new Sington();

public static Sington getInstance() { return sington};

private Sington() {}

}

案例: Runtime.getRuntime();

点评: 简单粗暴的实现方式

2、 懒汉式 

public class Sington {

public static Sington sington = null;

public static Sington getInstance() { 

if(sington == null)

sington = new Sington();

return sington;

}

private Sington() {}

}

点评:在单线程中是非常合适的但不适合多线程使用,那么怎么解决多线程问题呢,没错,可以使用synchronized关键字,具体实现如下:

public class Sington {

public static Sington sington = null;

public static  synchronized Sington getInstance() { 

if(sington == null)

sington = new Sington();

return sington;

}

private Sington() {}

}

细心的朋友会发现这样确实解决了多线程问题,但是每次调用该方法时都使用了同步机制,这多少会有些性能问题,因为其实我们只需要在第一次调用该方法时保证同步即可,那就是接下来的第三种方式。

3、 DCL (double check lock)  (推荐使用)

public class Sington {

public static Sington sington = null;

public static Sington getInstance() { 

if(sington == null) {// 该处判断避免不必要的同步

  sychronized(Sington.class) {

if(sington == null) {// 该处判断保证sington为null时才创建

sington = new Sington();

}

}

}

return sington;

}

private Sington() {}

}

点评: 这种实现方式是比较推荐的一种实现方式,在很多地方被使用,比如我们常用的ImageLoad图片框架便采用了这种实现方式。

注意: 其实在多线程特别复杂的环境下,该方式也不完全能保证正确。这个有机会再讲

4、 静态内部类单例模式 (推荐使用)

public class Sington {

private Sington() {}

public static Sington getInstance() { 

return SingtonHolder.sington;

}

private static class SingtonHolder {

private static final Sington sington = new Sington();

}

}

点评: 第一次加载Sington类时并不会实例化Singon,只有在第一次调用getInstance方法时才会创建,因为调用该方法虚拟机就会主动加载SingtonHolder类。这种方式几乎完美,既保证唯一性又是线程安全的

5、 借助容器实现单例模式

public class SingtonManger {

private static HashMap<String,Object>  objMap = new HashMap(String,Object);

private SingtonManger(){};

public static void registerService(String key, Object obj) {

if(!objMap.contains(key))

objMap.put(key,obj);

}

public static Object getService(String key) {

return objMap.get(key)

}

}

学安卓的朋友看到这个有没有觉得似曾相识,没错安卓里面的服务就是这种形式。有兴趣可以去看看安卓源码

点评: 这种方式适合管理多个单例

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: