单例模式是java中最常见的设计模式之一。它属于创建型模式,提供了一种创建对象的最佳模式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象的方式,可以直接访问,不需要创建对象。
概况简介:
意 图:保证一个类仅有一个实例,并提供访问他的全局访问点;
主要解决:一个全局适用的类的频繁创建与销毁;
何时使用:当你想控制是实例数目,节省系统资源的时候;
如何解决:判断系统是否有这个单例,如果有则返回,无,则创建;
关键代码:构造函数私有;
应用实例:
1、 一个班级只有一个班主任。
2、 设备管理器:打印机,在输出的时候不能两台打印机打印同一个文件,只允许一个操作。
优 点:单个实例存在,减少内存开销,尤其是频繁的创建和销毁实例;
避免对资源的多重占用。
缺 点:没有接口,不能继承,与单一职责冲突,一个类应该只关心内部逻辑,而不关心怎么样实例化。
应用场景:
1、生产唯一的序列号
2、Web计数器,刷新时缓存
3、创建一个对象需要消耗的资源过多时,比如I/O与数据库的连接。
注意事项:getInstance()方法需要使用同步锁synchronized(Singleton.class)防止多线程同时进入造成instance被多次实例化。
实现:
饿汉式:
是否Lazy初始化:否
是否多线程安全:是
实现难度:易
描述:这种方式常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会高。
缺点:类加载时就初始化,浪费内存。
它基于classloader机制避免了多线程的同步问题,不过,instance在类加载时就实例化,虽然导致类加载的原因很多种,在单例模式中,大多数都是getInstance()方法,但是也不确定有其他方式(或者其他静态方法)导致类加载,这时候初始化instance显然没有达到lazy loading的效果。
public class Singleton{
private static Singleton instance =new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
双检锁/双重检验锁(DCL):
是否Lazy初始化:是
是否多线程安全:是
实现难度:较复杂
描述:这种方式采用双锁机制,安全且在多线程的情况下能保持高性能
public class Singleton{
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getInstance(){
if(singleton ==null){
synchronized (Singleton.class){
if(singleton ==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。