单例模式
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)
}
}
学安卓的朋友看到这个有没有觉得似曾相识,没错安卓里面的服务就是这种形式。有兴趣可以去看看安卓源码
点评: 这种方式适合管理多个单例
简单的可以理解在系统中只存在一个实例对象
适用场合:
一个对象需要频繁创建和销毁
对象创建需要消耗一定的资源
一个对象即可满足需要
单例模式优点: 节约内存,提高性能,避免了大对象频繁创建的消耗
单例模式缺点: 不符合开闭原则,该类不支持拓展,当功能变化时修改代码是必然的
单例的几种实现方式:
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)
}
}
学安卓的朋友看到这个有没有觉得似曾相识,没错安卓里面的服务就是这种形式。有兴趣可以去看看安卓源码
点评: 这种方式适合管理多个单例
相关文章推荐
- android 换肤(2)——插件式无缝换肤(解析鸿洋大神的换肤流程)
- C++ placement new操作符
- 通比牛牛
- java数据结构之(顺序栈+链式栈)
- bash命令/文件管理-vim操作
- 路由器、交换机配置入门
- postgresql删除属性
- 【转载】OGRE中用到的设计模式
- SVN并行开发管理策略
- python egg
- 本周任务
- 简要介绍 LFW dataset
- Java设计模式之策略模式(Strategy)
- postgresql 修改属性
- 二叉树的创建与前序遍历(递归方式)
- bash命令/文件管理-基本命令
- HTML5笔记:跨域通讯、多线程、本地存储和多图片上传技术
- docker搭建Hadoop集群
- Qt实现停靠功能
- 【转载】Ogre:Beginner Tutorial 1: SceneNode, Entity,和SceneManager 结构