Java设计模式学习之单例模式

1.饿汉式,类加载的时候就创建一个对象(静态成员变量在类加载的时候初始化),不会带来线程安全问题,可能会带来效率问题

package singleton;

/**
 * @author Administrator 饿汉式 类加载的时候就创建一个单例对象,不会带来线程安全问题,可能会带来效率问题
 */
public class EagerSingleton {
	private static EagerSingleton singleInstance = new EagerSingleton();

	private EagerSingleton() {

	}

	public static EagerSingleton getInstance() {
		return singleInstance;
	}
}


2.懒汉式,只有当单例类用到的时候才会创建对象,非线程安全(多线程切换)

package singleton;

/**
 * 
 * @author Administrator 懒汉式 	只有当单例类用到的时候才会创建对象,非线程安全(多线程切换)
 */
public class LazySingleton {
	private static LazySingleton singleInstance = null;

	private LazySingleton() {

	}

	public static LazySingleton getInstance() {
		if (null == singleInstance) {
			singleInstance = new LazySingleton();
		}
		return singleInstance;
	}
}

2.1  懒汉式变种一,为了解决线程安全的问题,给获取实例的对象的方法加关键字synchronized同步(缺点:每次都要同步,影响性能)


package singleton;

public class LazySynchronizedSingleton {
	private static LazySynchronizedSingleton singletonInstance = null;

	private LazySynchronizedSingleton() {

	}

	public synchronized static LazySynchronizedSingleton getInstance() {
		if (null == singletonInstance) {
			singletonInstance = new LazySynchronizedSingleton();
		}
		return singletonInstance;
	}

}

2.2  懒汉式变种二,双检锁(既解决了线程安全问题,同时没有性能影响)


package singleton;

/**
 * 
 * @author Administrator
 *	双检锁
 */
public class DoubleCheckLockSingleton {
	private static DoubleCheckLockSingleton singleInstance = null;

	private DoubleCheckLockSingleton() {
	}

	public static DoubleCheckLockSingleton getInstance() {
		if (null == singleInstance) {
			synchronized (DoubleCheckLockSingleton.class) {
				if (null == singleInstance) {
					singleInstance = new DoubleCheckLockSingleton();
				}
			}
		}
		return singleInstance;
	}
}


2.3   懒汉式之变种三,静态内部类(效果同上)

package singleton;

/**
 * 
 * @author Administrator
 *	静态内部类  
 */
public class StaticInnerClassSingleton {
	private static class LazyHolder {
		private static final StaticInnerClassSingleton instance = new StaticInnerClassSingleton();
	}

	private StaticInnerClassSingleton() {
	}

	public static StaticInnerClassSingleton getInstance() {
		return LazyHolder.instance;
	}
}

2017-11-30 11:41更新

这里更新主要是为了解释下双检锁的两次判断对象是否为NULL,

第一次判断为NULL是为了提高效率,因为在实际项目中大多数情况下不会用到并发,所以不需要在每一次获取实例对象时

都要加锁,这样会导致效率降低,否则双检锁和在方法上加synchronized关键字的做法也没什么区别了。

第二次判断为NULL是为了防止出现两个实例对象,这样会失去了单例的意义,想象下这种场景,在极高并发场景下,两个线程都进入第一个if判断,一个

线程拿到了锁,另一个没有拿到,阻塞在外面,拿到锁的线程实例化了一个对象,然后释放锁,然而等待的线程并不知道已经有一个实例被初始化了,因此

有实例化一个对象,这就违反了单例的原则, 因此,需要在锁中再判断是否有对象已被实例化。

~end




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值