我眼中的单例模式
来源:互联网 发布:怎么用c语言编写软件 编辑:程序博客网 时间:2024/05/16 10:23
单例模式是一中很常用的设计模式,写代码的过程经常有用到.
什么情况下需要单例模式
当你只想持有一个实例的时候.这个实例的生命周期是跟随进程的,一旦初始化就常驻内存,并且只有一个实例.
举个例子,如果是一个安卓的工程,Application这个类就是单例的,我只会需要一份.如果是一个普通的任意一个应用,为了表达平台信息的等,这个类也不太可能多处实例化,一般也只需要一个.
单例的坏处在于会占这内存不放.如果需要释放内存,还要手动的操作.
单例模式的示例
1.先上一个最简单的单例模式,这个模式也是非线程安全的
public class SingleInstance { //private 保证了不能在类的外部来构造一个实例 //static 保证了与类相关的,只能有一份 private static SingleInstance sSingleInstance; private String mName; private SingleInstance(String name) { mName = name; } public static SingleInstance getInstance() { if (null == sSingleInstance) { sSingleInstance = new SingleInstance("非线程安全 饱汉(也叫懒初始化) 单例模式"); } return sSingleInstance; }}
2.例子1中的单例,当面临多线程访问的时候,会有初始化的问题.下面给出一个最简单粗暴的线程安全的例子
private static SingleInstance sSingleInstance; private String mName; private SingleInstance(String name) { mName = name; } //对,与你想的一样,就是加一个同步的关键字 public static synchronized SingleInstance getInstance() { if (null == sSingleInstance) { sSingleInstance = new SingleInstance("非线程安全 饱汉(也叫懒 初始化) 单例模式"); } return sSingleInstance; }
3.例子2中的同步关键字,锁的范围太大,就有了改进版
//如果是下面这样的加锁方式,是一定要有volatile关键字的 private static volatile SafeSingleInstance sSingleInstance; private String mName; private SafeSingleInstance(String name) { mName = name; } //可以直接把整个方法锁住,不过代价比较大,这种方法是直接锁getInstance方法的改良版 public static SafeSingleInstance getInstance() { if (null == sSingleInstance) { synchronized (SafeSingleInstance.class) { if (null == sSingleInstance) { sSingleInstance = new SafeSingleInstance("线程安全 双重检查的 单例模式"); } } } return sSingleInstance; } public String getName() { return mName; }
4.与例子3相似的,还有一种通过static方法来完成的线程安全
private static SafeSingleInstance2 safeSingleInstance2; private String mName; private SafeSingleInstance2(String name) { mName = name; } //实现这种方式的原理是,因为在类的初始化过程中对于一些static的类型的初始化时,系统级别的有加上锁的,不需要再显示的加上锁 private static class SafeSingleInstanceHolder { public static SafeSingleInstance2 holder = new SafeSingleInstance2("线程安全 初始化方式改造 单例模式"); } public static SafeSingleInstance2 getInstance() { return SafeSingleInstanceHolder.holder; } public String getName() { return mName; }
5.以上的例子都是比较友善的方式,只有当你需要使用的时候才会加载.也有一种暴力的线程安全,就是一旦类加载就初始化,也叫做饿汉单例模式
//这种单例模式的坏处在于,只要加载类,类就完成了实例化,不是一个友好的设计 private static SafeSingleInstance1 sSingleInstance = new SafeSingleInstance1("线程安全 饿汉 单例模式"); private String mName; private SafeSingleInstance1(String name) { mName = name; } public static SafeSingleInstance1 getInstance() { return sSingleInstance; } public String getName() { return mName; }
为了更好的查看,以代码的方式进行了记录.详情请查看DesignPattern中的 com.arron.pattern.single下的内容.戳我查看详情
阅读全文
0 0
- 我眼中的单例模式
- 我眼中的MVC模式
- 我眼中的策略模式
- 我眼中的设计模式
- 我眼中的MVC模式
- 我眼中的命令模式
- 我眼中的观察者模式
- 我眼中的代理模式
- 我眼中的设计模式-适配器模式
- 我眼中的设计模式 ----策略模式
- 我眼中的设计模式(一)
- 我眼中的设计模式(二)
- 我眼中的设计模式(三)
- 我眼中的设计模式(2)
- 我眼中的设计模式(3)
- 我眼中的设计模式(4)
- 我眼中的设计模式(5)
- 我眼中的设计模式(6)
- (三)spring cloud云服务
- Jenkins构建
- entry、map、iterator之间的联系
- hashmap解析一
- CentOS 6.5 安装 MySQL 5.6.15并修改MySQL的root用户密码
- 我眼中的单例模式
- Eclipse中取消生成TODO Auto-generated method stub
- 视频监控安防平台-oracle和mysql数据库连接池
- 简单工厂模式
- jqgrid 实现基础的单行编辑功能
- 数学家祖冲之的故事
- eclipse中配置server中选择tomcat8无法进行下一步处理 在创建server的时候,选择tomcat8后,server name为空,并且无法手动输入,同时无法进行下一步操作。 解决方
- 引入Bootstrap老是报错:the server responded with a status of 404 (Not Found)
- js iframe 通过postMessage 向父页面跨域传数据