单例模式

单例模式,独一无二的对象,提供一个全局访问点。

        1. 非多线程下使用。

/**
 * 单例模式,提供全局访问点
 * 
 * @author fuzhengchao
 * 
 */
public class Singleton {
	private static Singleton uniqueInstance;

	private Singleton() {
		// 一些初始化操作
	}

	public static Singleton getInstance() {
		if (null == uniqueInstance) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
}

      由getInstance()方法的实现我们可以看出,单例模式还有延迟实例化的作用,在第一次需要的时候才创建对象。


      但是这种实现方法在多线程的时候就有问题了,当多个线程同时进入if (null == uniqueInstance) 和uniqueInstance = new Singleton();

      之间时,就会创建多个对象,这就违背了单例模式的设计初衷了。


 2. 多线程下单例模式的实现。

     2.1 如果多线程线程数不是很多,程序对性能要求不是很高,我们可以这样设计:

/**
 * 单例模式,提供全局访问点
 * 
 * @author fuzhengchao
 * 
 */
public class Singleton {
	private static Singleton uniqueInstance;

	private Singleton() {
		// 一些初始化操作
	}

	// 加锁
	public static synchronized Singleton getInstance() {
		if (null == uniqueInstance) {
			uniqueInstance = new Singleton();
		}
		return uniqueInstance;
	}
}

       把getInstance()加锁,这样就能保证多个线程不能同时进入创建多个对象了。 但为什么这样做会影响程序性能呢?如果线程过多,每次调用getInstance()方法时,只能一个线程一个线程进入,那么这里就会造成很多线程等待同步,从而影响性能。

     2.2 使用“急切”创建实例,而不用延迟实例化的做法。

         

/**
 * 单例模式,提供全局访问点
 * 
 * @author fuzhengchao
 * 
 */
public class Singleton {
	private static Singleton uniqueInstance = new Singleton();

	private Singleton() {
		// 一些初始化操作
	}

	public static Singleton getInstance() {
		return uniqueInstance;
	}
}

        从上面的代码我们可以看出,我们取消了加锁操作,直接在静态初始化中创建了对象,我们依赖JVM在加载这个类是创建了唯一的单例,后面不会在创建了。这样再多的线        程同时操作也不会出现等待同步影响性能了,但是这样新问题又出现了,我们的单例不能延迟实例化了,程序一开始就创建了这个对象一直到程序退出,如果中间运用这个         单例在程序很靠后,或则很少情况下,这样就比较浪费资源了。

       2.3 用“双重检测加锁”,在getInstance()中减少使用同步

/**
 * 单例模式,提供全局访问点
 * 
 * @author fuzhengchao
 * 
 */
public class Singleton {
	private static Singleton uniqueInstance;

	private Singleton() {
		// 一些初始化操作
	}

	// 加锁
	public static Singleton getInstance() {
		if (null == uniqueInstance) {
			synchronized ((Singleton.class)) {
				if (null == uniqueInstance) {
					uniqueInstance = new Singleton();
				}
			}
		}
		return uniqueInstance;
	}
}

        这样只有在第一次创建对象时,多个线程同时进入第一个null == uniqueInstance和synchronizede()之间时,一个线程进去创建对象,其它线程获取对象会出现等待同步。只要对象一旦创建成功,后续的线程都直接在第一个null == unigueInstance 退出,后面就不会有性能问题了。但是已经进入null == uniqueInstance 和synchronized之间的线程还得等待同步。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值