Singleton Model是一个比较简单的模式,类图结构也很简单,不过实现却是有好几个版本。
为什么会有单例模式?在一些共享资源上,他要求全局一致的处理结构。一些全局的资源,比如线程池,缓冲区等需要又要给类来管理这些资源,这个类实例化时候只能实例化一个,否则如果出现多个实例会出现多个对象对资源描述的不一致性。
单例模式:In software engineering, the singleton pattern is a design pattern that restricts the instantiation of a class to one object.并提供全局访问接口。
经典模式:
public class Singleton { private static Singleton instance; private Singleton() //构造函数 私有 { } public Singleton getInstance() { if(!instance) { instance = new Singleton(); } return instance; } }
经典模式是简单的,但是在多线程的情况下,容易出现问题,所以又同步块的模式,双锁的模式,饥渴模式
在getInstance加上sysnchronized可以解决同步的问题
同步块的方法:
public class Singleton { private static Singleton instance; private Singleton() { } public synchronized Singleton getInstance() { if(!instance) { instance = new Singleton(); } return instance; } }
简单地加上同步块是很容易的,但是问题也是很显然的,效率会很低,但是仔细考虑,会发现在第一次初始化的时候才会出现需要同步的问题,初始化之后就不会出现这样情况了。于是出现了双锁模式。
public class Singleton { private static Singleton instance; private Singleton() { } public Singleton getInstance() { if(!instance) { synchronized(Singleton.
class
) { //not sychronized(instance) instance = new Singleton(); } } return instance; } }
首先判定instance是否为空,如果为空那么就会出现同步问题,所以使用同步块,当instance已经实例化好了,那么就不需要同步了,后面使用也不许在同步了,这种方式比较好
还有另外一种方法,就是饥汉模式,不采用延迟初始化的方法,在声明的同时就实例化这个实力,在JVM加载这个类的时候就初始化;
public class Singleton { private static Singleton instance = new Singleton(); private Singleton() { } public Singleton getInstance() { return instance; } }
这样也会出现一个问题,那就是当出现类被多次加载的时候就会出现这个问题。有多个实例,这违反了单例模式的规则。