单例模式的几种实现方式和各自优缺点分析

时间:2015-07-24作者:klpeng分类:IT综合浏览:1989评论:0

一  饿汉式单例模式 这种方式占空间,典型的以空间换取时间

代码如下:

/**
 * 饿汉式单例模式 这种方式占空间,典型的以空间换取时间
 * 
 * @author Jerry
 * @date 2014年5月29日
 */
public class EHanShi {
	// 饿汉式,饿汉比较饿,刚开始就直接实例化了。
	private static final EHanShi singleton = new EHanShi();

	// 私有化构造函数,防止外部实例化
	private EHanShi() {
	}

	/**
	 * 提供一个全局方法,获取实例
	 * 
	 * @return EHanShi的实例
	 */
	public static EHanShi getInstance() {
		return singleton;
	}
}

二  懒汉式,懒汉比较懒,所以只在第一次请求时,才实例化 这种方式执行效率比较低 ,典型的以时间换取空间

代码如下;

/**
 * 懒汉式,懒汉比较懒,所以只在第一次请求时,才实例化 这种方式执行效率比较低 ,典型的以时间换取空间
 * 
 * @author Jerry
 * @date 2014年5月29日
 */
public class LanHanShi {
	private static LanHanShi singleton = null;

	// 私有化构造函数,防止外部实例化
	private LanHanShi() {
	}

	/**
	 * 加上synchronized是为了线程安全
	 * 
	 * @return LanHanShi的实例
	 */
	public static synchronized LanHanShi getInstance() {
		// 判断是否为空
		if (singleton == null) {
			singleton = new LanHanShi();
		}
		return singleton;
	}
}

三 双重检查加锁懒汉式 所谓双重检查加锁机制是指:并不是每次进入getInstance方法都需要同步

代码如下:

/**
 * 双重检查加锁懒汉式 所谓双重检查加锁机制是指:并不是每次进入getInstance方法都需要同步,
 * 而是先不同步,进入方法过后,先检查实例是否存在,如果不存在 才进入下面的同步块,这是第一重检查。进入同步快过后,
 * 再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例, 这是第二重检查。
 * 
 * 要使用到关键字volatile:被volatile修饰的变量的值,将不会被本地线程缓存,
 * 所有对该变量的读写都是直接操作共享内存,从而去确保多个线程能正确的处理该变量(推荐java5以上jdk使用)
 * 
 * @author Jerry
 * @date 2014年5月29日
 */
public class DoubleCheckLockLanHanShi {
	private volatile static DoubleCheckLockLanHanShi singleton = null;
	// 私有化构造函数,防止外部实例化
	private DoubleCheckLockLanHanShi() {
	}

	public static DoubleCheckLockLanHanShi getInstance() {
		// 第一重判断
		if (singleton == null) {
			synchronized (DoubleCheckLockLanHanShi.class) {
				// 第二重判断
				if (singleton == null) {
					singleton = new DoubleCheckLockLanHanShi();
				}
			}
		}
		return singleton;
	}
}


四 Lazy initialization holder

代码如下:

/**
 * 更好的单利实现模式,即实现了延迟加载,又实现了线程安全, 这里使用到java类级内部类,和多线程缺省同步锁的知识 类级内部类指的是:有static
 * 修饰的成员式内部类。没有static修饰的成员式内部类称为对象级内部类 类级内部类可以定义静态的方法,相较于其外部类的成员,只在第一次被使用时才会被加载。
 * 多线程缺省同步锁:在某些情况下,jvm已经隐含的为您执行同步。 · 由静态初始化器(在静态字段上或static{}块中的初始化器)初始化数据时 ·
 * 访问final字段时 · 在创建线程之前创建对象时 · 线程可以看见它将要处理的对象时
 * 
 * @author Jerry
 * @date 2014年5月29日
 */
public class BetterSingleton {
	/**
	 * 类级内部类指的是:有static 修饰的成员式内部类。没有static修饰的成员式内部类称为对象级内部类
	 * 类级内部类可以定义静态的方法,相较于其外部类的成员,只在第一次被使用时才会被加载。
	 * 
	 * @author Jerry
	 * @date 2014年5月29日
	 */
	private static class SingletonHolder {
		/**
		 * 静态初始化器,由JVM来保证线程安全
		 */
		private static BetterSingleton singleton = new BetterSingleton();

	}

	// 私有化构造函数,防止外部实例化
	private BetterSingleton() {
	}

	public static BetterSingleton getInSingleton() {
		return SingletonHolder.singleton;
	}
}

五 枚举类型的单例

代码如下:

/**
 * 枚举类型的单例模式
 * 
 * @author Jerry
 * @date 2014年5月29日
 */
public enum EnumSingleton {
	/**
	 * 定义一个枚举的元素,它就代表了EnumSingleton的一个实例
	 */
	singleton;
	/**
	 * 单例可以有自己的操作
	 */
	public void singletonOperation() {
		// 功能处理
	}
}


打赏
文章版权声明:除非注明,否则均为彭超的博客原创文章,转载或复制请以超链接形式并注明出处。
相关推荐

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

猜你喜欢