一。单例模式的定义:
保证一个类仅有一个实例,并提供一个全局访问点。
单例模式的实现呢大概有两种:一种是懒汉式,还有一种是饿汉式
饿汉式呢就是在类加载时呢就已经创建了单例对象,例如:
//单例模式之饿汉式
class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return instance;
}
}
除了饿汉式单例,还有一种经典的懒汉式单例;
/**
* LazySingleton 懒汉式单例
*/
public class LazySingleton {
private static LazySingleton instance = null;
private LazySingleton() {
}
public static LazySingleton getInstance() {
if (instance == null) {
synchronized(LazySingleton.class){
if(instance==null){
instance = new LazySingleton();
}
}
}
return instance;
}
}
饿汉式单例类与懒汉式单例类比较
饿汉式在类被加载时就将自己实例化,则无需考虑多线程访问问题,但在资源利用效率上说却不及懒汉式,但懒汉式,在多线程问题上需要通过双重检查锁定等机制进行控制,这将导致系统性能受到一定影响。
我在《研磨设计模式》中看到了另一种实现方式,
/**
* Singleton
*/
public class Singleton {
/**
* 内部类,也是静态成员式的内部类,该内部类的实例与外部实例没有
* 任何绑定关系,而且只有被调用时才会装载,从而实现延迟加载
*/
private static class SingletonHolder {
// 静态化初始容器 有jvm 保证线程安全
private static Singleton instance = new Singleton();
}
private Singleton() {
}
public static Singleton getInstance() {
return SingletonHolder.instance;
}
}
单例模式的优点:
在内存中只有一个对象,因此可以节约系统资源,提高系统的性能。单例模式提供了对唯一实例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。允许可变数目的实例。基于单例模式我们可以进行扩展,使用与单例控制相似的方法来获得指定个数的对象实例,既节省系统资源,又解决了单例单例对象共享过多有损性能的问题。
单例模式的主要缺点如下: 由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。 单例类的职责过重,在一定程度上违背了“单一职责原则”。因为单例类既充当了工厂角色,提供了工厂方法,同时又充当了产品角色,包含一些业务方法,将产品的创建和产品的本身的功能融合到一起。