- 定义
- 意图
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
- 主要解决
一个全局使用的类频繁地创建与销毁。
- 何时使用
当您想控制实例数目,节省系统资源的时候。
- 如何解决
判断系统是否已经有这个单例,如果有则返回,如果没有则创建。
- 关键代码
构造函数是私有的。
- 优点
1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
2、避免对资源的多重占用(比如写文件操作)。
- 缺点
没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
类图
/***
* 懒汉模式
*
* 1 volatile 此处保证内存可见性
* 2 synchronized 保证同一时间 只有一个线程访问 getLazySingleton() 方法
*
*/
public class LazySingleton {
private static volatile LazySingleton lazySingleton;
private LazySingleton(){};
public static synchronized LazySingleton getLazySingleton(){
if (lazySingleton == null){
lazySingleton = new LazySingleton();
}
return lazySingleton;
}
}
/***
* 饿汉模式
*
* 对象在初始化时被创建在方法区中
*
*/
public class HungrySingleton {
private static HungrySingleton hungrySingleton;
static {
hungrySingleton = new HungrySingleton();
}
public static HungrySingleton getHungrySingleton(){
return hungrySingleton;
}
private HungrySingleton (){}
}
/***
* 双重检测模式
*
* 1 volatile 此处保证内存可见性 指令冲排序
* 2 synchronized 保证同一时间 只有一个线程访问
* 3 第一个if doubleCheckSingleton == null 避免多线程下同时阻塞到 synchronized
* 4 第二个if 主要避免多个线程同时拿到锁到情况下创建单一实例
*
*/
public class DoubleCheckSingleton {
private static volatile DoubleCheckSingleton doubleCheckSingleton;
private DoubleCheckSingleton(){}
public static DoubleCheckSingleton getDoubleCheckSingleton(){
if (doubleCheckSingleton == null){
synchronized (DoubleCheckSingleton.class){
if (doubleCheckSingleton == null){
doubleCheckSingleton = new DoubleCheckSingleton();
}
}
}
return doubleCheckSingleton;
}
}
/***
* 枚举模式 实现单例
*
* 1 可以防止序列化创建多个实例
* 2 可以防止反射创建多个实例
*
*/
public enum EnumSingleton {
INSTANCE( );
private S instance;
EnumSingleton() {
instance = new S();
}
public S getInstance() {
return instance;
}
}
class S{
}
- 其他模式
- ThreadLocal 方法实现
- 容器实现
网友评论