设计模式之单例模式
什么是单例模式
单例模式,是一种常用的软件设计模式。
在它的核心结构中只包含一个被称为单例的特殊类。
通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。
单例模式分别有懒汉模式与饿汉模式。
懒汉模式:
public class Lazy { //将构造方法私有化,不循序外部直接创建对象 private Lazy(){ } //2.声明类的唯一实例 private static Lazy instance; //3.提供一个用于获取实例的方法 public static synchronized Lazy getInstance(){ //加同步锁 if(instance == null){ instance = new Lazy(); } return instance; } }
注:为何称他为懒汉呢?我们可以把他当成一个酒店员工,因为他比较懒,所以每次都要等客人来就餐的时候(Lazy.getInstance()),他才开始去生产,instance = new Lazy()。
饿汉模式:
public class Starving { //1.将构造方法私有化,不允许外部直接创建对象 private Starving() { } //2.创建类的唯一实例 private static Starving instance = new Starving(); //提供一个用于获取实例的方法 //需要注意的是,我们这个方法属于对象,不是类方法 //public Starving getInstance() { //return instance; //} //3.提供一个用于获取实例的私有的类的静态成员方法 public static Starving getInstance() { return instance; } }
注:为何称他为饿汉呢?可以想象成一个饭点时间,就餐时间还没到(Starving.getInstance),饿汉就已经准备好菜啦(private static Starving instance = new Starving()),一到时间马上吃饭,不用再等待上菜。
双重锁的形式:
public class Singleton { private static volatile Singleton instance=null; private Singleton() { //do something } public static Singleton getInstance( ) { //这个模式将同步内容下方到if内部,提高了执行的效率, //不必每次获取对象时都进行同步,只有第一次才同步,创建了以后就没必要了。 if (instance == null) { synchronized(Singleton.class){ if (instance == null) { instance = new Singleton(); } } } return instance; } }
注:这种模式中双重判断加同步的方式,比第一个例子中的效率大大提升,因为如果单层if判断,在服务器允许的情况下,
假设有一百个线程,耗费的时间为100*(同步判断时间+if判断时间),而如果双重if判断,100的线程可以同时if判断,理论消耗的时间只有一个if判断的时间。
所以如果面对高并发的情况,而且采用的是懒汉模式,最好的选择就是双重判断加同步的方式。
总结与区别:
饿汉模式的特点是加载类时比较慢,但运行时获取对象的速度比较快,线程安全。
饿汉模式是线程安全的,在类创建的同时就已经创建好一个静态的对象供系统使用,以后不在改变。
懒汉模式的特点是加载类时比较快,但是在运行时获取对象的速度比较慢,线程不安全。
懒汉模式如果在创建实例对象时不加上synchronized则会导致对象的访问不是线程安全的。
所以在此推荐大家使用饿汉模式。