几种单例模式的使用及比较
来源:互联网 发布:软件项目总结 编辑:程序博客网 时间:2024/06/18 17:34
单例的使用一般分为三步:
(1)最简单的一种方式
<span style="white-space:pre"></span>private static AudioManager mInstance; //第一步:一个私有静态的类成员变量private AudioManager() {} //第二步:一个私有的构造方法public static AudioManager getInstance() {//第三步:一个public的对外获取实例的方法<span style="white-space:pre"></span>if (mInstance == null) {mInstance = new AudioManager();}return mInstance;}
这种方式只有在单线程的时候工作正常,设想在多线程的情况下,当两个线程同时运行到判断mInstance是否为null的if语句,并且mInstance没有创建时,这时两个线程都回去创建一个实例,此时就不符合单例的要求了。
(2)能在多线程下工作但线率不高的方式
由(1)可知,为了让其能在多线程下正常工作,需要加上一把同步锁,修改如下:
<span style="white-space:pre"></span><span style="font-size:18px;">private static AudioManager mInstance; //第一步:一个私有静态的类成员变量private AudioManager() {} //第二步:一个私有的构造方法public static AudioManager getInstance() {//第三步:一个public的对外获取实例的方法synchronized (AudioManager.class) {<span style="white-space:pre"></span>if (mInstance == null) {<span style="white-space:pre"></span>mInstance = new AudioManager();}}return mInstance;}</span>通过这种加同步锁的方式,我们可以保证在多线程的环境下只得到一个该类的实例,但我们每次通过getInstance()方法去取实例时,都会试图加上一个同步锁,而加锁是一个非常耗时的操作,在该实例存在时我们就应该尽量避免再去加锁。
(3)推荐使用的方式
<span style="font-size: 18px; "><span style="white-space:pre"></span>/** * 通过单例实现获取本类(AudioManager)对象 */private static AudioManager mInstance; //第一步:一个私有静态的类成员变量private AudioManager() {} //第二步:一个私有的构造方法public static AudioManager getInstance() {//第三步:一个public的对外获取实例的方法if (mInstance == null) {synchronized (AudioManager.class) {if (mInstance == null) {mInstance = new AudioManager();}}}return mInstance;}</span>
如果获取实例时需要给构造方法传入参数,直接在getInstance()里面加入参数即可,如:
<span style="font-size:18px;"><span style="white-space:pre"></span>private String mDir;</span>
<span style="font-size:18px;"><span style="white-space:pre"></span>private static AudioManager mInstance;//第一步:一个私有静态的类成员变量private AudioManager(String dir) {//第二步:一个私有的构造方法mDir = dir;}public static AudioManager getInstance(String dir) {//第三步:一个public的对外获取实例的方法if (mInstance == null) {synchronized (AudioManager.class) {if (mInstance == null) {mInstance = new AudioManager(dir);}}}return mInstance;}</span>
上面的getInstance方法里面通过两次 if 判断,控制只有当mInstance为null即没有创建时,才需要加锁操作。因为只在第一次的时候mInstance为null,因此只有在第一次试图创建实例的时候才需要加锁,相对于第二种方式效率会有很大的提高。
4 0
- 几种单例模式的使用及比较
- 大话设计模式之简单工厂模式、抽象工厂模式及工厂方法模式的比较
- 大话设计模式之简单工厂模式、抽象工厂模式及工厂方法模式的比较
- C#工厂模式的几种实现方法及比较
- 抽象工厂模式的几种实现方法及比较
- Foreach循环及For性能及使用上的比较
- 类与结构的比较及它们的使用选择
- Java的代理和CGLib的比较及使用
- 邻接表的使用及和vector的比较
- 对象的比较及hashCode、equals方法的使用
- 设计模式之———单例模式的问题及效率比较
- 单例模式的创建及使用
- .net中for与foreach的比较及使用。
- 各大浏览器的使用心得及比较
- lucene4.0各内置分析器的使用及比较
- 比较全的Spark中的函数使用及编程模型
- BeautifulSoup中各种html解析器的比较及使用
- synchronized与ReentrantLock的介绍、使用、适合场景及比较
- 5月记-电面、学习、考试、纠结
- 28.数据存储 plist 偏好设置 归档
- centos下部署ngnix和php
- Jersey+EclipseJavaEE+Apache-Tomcat8 开发Rest服务
- Apache Thrift - 可伸缩的跨语言服务开发框架
- 几种单例模式的使用及比较
- linux下jvm 参数调优
- rpmreaper和rpmorphan简介
- 在cubieboard2里安装pptpd碰到的依赖问题处理
- 算法导论 最坏情况为线性时间的选择算法 9.3-8 9.3-9
- android 安全机制
- C#中Math.Round()实现中国式四舍五入
- UIImageView添加UIButton时,按钮点击事件无效
- bzoj1208 splay伸展树