设计模式第六讲:单例模式(附优化议案)

设计模式第六讲:单例模式(附优化方案)

单例模式

一:模式定义


一个类有且仅有一个实例,并且自行实例化向整个系统提供。


二:模式特点


通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。


三:使用场景


希望在系统中某个类的对象只能存在一个。


四:具体实现


单例模式有两种写法:

1.懒汉式   

2.饿汉式


懒汉式实现:


public class Single {
    private static Single instance;
    private Singleton (){}

   public static Single getInstance() {
	if (instance == null) {
	    instance = new Single();
	}
	return instance;
    }
}


懒汉式的特点式,实例的对象是在用到的时候才创建,这样就会导致线程不安全,因为如果有两个线程同时getInstance()就有可能创建出来两个实例,破坏了单例的特性。


懒汉式改进实现:


public class Single {
    private static Single instance;
    private Single(){}
    public static synchronized Single getInstance() {
	if (instance == null) {
	    instance = new Single();
	}
	return instance;
    }
}


加入同步锁,在多线程下可以很好地工作


饿汉式实现:


public class Single {
    private static Singlet instance = new Singlet();
    private Single(){}
    public static Single getInstance() {
	return instance;
    }
}

饿汉式的实现,是利用了classloader机制,在类加载的时候既完成了实例化,这样就不存在多线程的安全问题了,但是这种预加载,也有占用系统大量资源的风险。


以上的两种实现方法,无论哪种,都会存在一定的缺点,下面来做一下优化,使得兼具两种形式的优点:


public class Singlet {
    private static class SingleHolder {
	private static final Single INSTANCE = new Single();
    }
    private Single (){}
    public static final Single getInstance() {
	return SingleHolder.INSTANCE;
    }
}

这种实现方式,既可以实现多线程的安全,也可以实现使用时才加载的要求,因为其内部的SingleHolder静态类在Singlet加载的时候并不会加载,只有在使用getInstance()才会触发加载。