单例模式

单例模式

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

适用场合:

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

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

一个对象即可满足需要

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

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


单例的几种实现方式: 

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)

}

}

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

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




 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值