浅谈单例模式

166 阅读2分钟

单例模式通俗的说就是在一个应用程序中某一个类的对象是唯一的,无论在哪里操作这个对象都是操作的同一个对象。本篇不仅介绍关于单例模式的两种类型,而且介绍实际开发中常使用的具体实现方法。

单例模式分成两种类型,分别是饿汉模式和懒汉模式。

饿汉模式

饿汉模式是创建了一个静态对象并且直接提供到外部。 由于静态对象是在类加载的时候就创建了,并不一定是在使用的时候才创建,所以称之为饿汉模式。

/**
 * @author BeautifulSoup
 * 单例模式的饿汉模式
 */
public class Singleton {
	
	//构造方法私有化
	private Singleton(){
		
	}
	
	//创建类的唯一实例
	private static Singleton singleton=new Singleton();//类加载的时候就创建实例,
	
	//提供用于获取实例的方法
	public static Singleton getInstance(){
		return singleton;
	}
}	

懒汉模式 懒汉模式与饿汉模式的区别在于在定义一个对象的时候,并不直接实例化,只有当使用该对象的时候才会创建实例对象。

public class Singleton {
	
	private Singleton(){
	}
	
	private static Singleton singleton;//仅仅声明实体并不实例化
	
	public static Singleton getInstance(){
		if(null==singleton){
			singleton=new Singleton();
		}
		return singleton;	
	}
	
}

因此,饿汉模式是加载类的时候比较慢,运行时获取对象的速度比较快,并且饿汉模式是线程安全的;而懒汉模式是加载类的时候比较快,运行时获取对象的速度比较慢,并且懒汉模式线程是不安全的。

通过上面的介绍也可以知道,对于饿汉模式和懒汉模式,两者都有利弊。所以在实际开发中必然需要有一种更好的实现方法。

对于饿汉模式的优化-------使用静态内部类:

public class Singleton {
	private static class Holder{
		private static final Singleton instance=new Singleton();
	}
	public static Singleton getInstance(){
		return Holder.instance;
	}
}	

对于懒汉模式的优化-----线程安全的检查锁:

public class DoubleCheck {
	private volatile static DoubleCheck ins;//volatile能够起到禁止指令的重排序优化的作用
	private DoubleCheck(){
	}
	public static DoubleCheck getInstance(){
		if(null==ins){		//检查
			synchronized(DoubleCheck.class){
				if(null==ins){
					ins=new DoubleCheck();
				}
			}
		}
		return ins;
	}
}