码迷,mamicode.com
首页 > 其他好文 > 详细

几种单例模式的使用及比较

时间:2015-05-25 18:44:06      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

单例的使用一般分为三步:

(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,因此只有在第一次试图创建实例的时候才需要加锁,相对于第二种方式效率会有很大的提高。







几种单例模式的使用及比较

标签:

原文地址:http://blog.csdn.net/shakespeare001/article/details/45971025

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!