单例模式
单例模式是Java中最简单的设计模式之一,这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供一种访问其唯一对象的方式,可以直接访问,不要要实例化该类的对象。
注意:
1)单例类只能有一个实例
2)单例类必须自己创建自己的唯一实例
3)单例类必须给所有其他对象提供这一实例。
创建意图与使用步骤
意图: 一个类仅有一个实例,提供一个访问它的全局访问点
主要解决 : 一个全局使用的类频繁的创建与销毁
何时使用: 当想控制实例数目 节省系统资源时
如何解决: 判断系统是否已有单例 有则返回 无则创建
关键: 构造函数私有
单例模式的几种实现方式
1.懒汉式(线程不安全)
最基本的实现方式 不支持多线程
实例
public class Singleton{
//创建对象
private static Singleton instance;
//构造函数private 这样类就不会被实例化
private Singleton(){}
//判断是否存在 根据判断是否存在来获取对象
public static Singleton getInstance(){
if(instance==null){
instance = new Singleton();
}
return instance;
}
}
2.懒汉式(线程安全)
第一次调用必须初始化 避免内存浪费 加锁导致效率很低
实例
public class Singleton{
private static Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if (instance==null){
instance = new Singleton();
}
return instance;
}
}
3.饿汉式(线程安全)
没有加锁 执行效率高 类加载时就初始化 浪费内存 这种方式常用 容易产生垃圾对象
实例
public class Singleton{
private static Singleton instance = new Singleton();
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
4.双重锁(double-checked locking)
双锁机制 安全且在多线程情况下能保持高性能
实例
public class Singleton{
private volatile static Singleton singleton;
private Singleton(){}
public static Singleton getSingleton(){
if (singleton==null){
synchronized (Singleton.class){
if (singleton==null){
singleton = new Singleton();
}
}
}
return singleton;
}
}
5.登记式(静态内部类)
同双重锁功效一样 但实现更加简单 这种方式只适用于静态域
实例
public class Singleton{
private static class SingletonHolder{
private static final Singleton INSTANCE = new Singleton();
}
private Singleton(){}
public static final Singleton getInstance(){
return SingletonHolder.INSTANCE;
}
}
6.枚举
自动支持序列化机制 绝对防止多次实例化 更为简洁
实例
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
建议
一般情况下 不建议使用第1种和第2种懒汉方式
建议使用第3种饿汉方式
只有在要明确实现 lazy loading 效果时 才会使用第 5 种登记方式
如果涉及到反序列化创建对象时 可以尝试使用第 6 种枚举方式
如果有其他特殊的需求 可以考虑使用第 4 种双检锁方式
评论