单例模式
- 保证某个类只存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)
以下模式斜体为推荐使用
- 在
JDK
中,java.lang.Runtime
就是经典的单例模式(饿汉式) - 使用场景:需要频繁的进行创建和销毁对象,创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、平凡访问数据库或文件的对象(如数据源、session工厂等)
1 饿汉式(静态变量)
实现步骤:
- 构造器私有化
- 类的内部创建对象
- 向外暴露一个静态公共方法
- 代码实现
优缺点:
- 写法简单,在类加载的时候即完成了实例化,避免了线程同步问题。
- 没有达到Lazy Loading效果,可能会造成内存浪费。
2 饿汉式(静态代码块)
本质同上
3 懒汉式(线程不安全)
代码实现:
class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null)
instance = new Singleton();
return instance;
}
}
优缺点:
- 起到了lazy loading效果,但只能在单线程下使用
- 实际开发不推荐使用
4 懒汉式(线程安全,同步方法)
代码实现:
class Singleton{
private static Singleton instance;
private Singleton(){}
//在方法上加了synchronized
public static synchronized Singleton getInstance(){
if(instance == null)
instance = new Singleton();
return instance;
}
}
优缺点:
- 效率太低
- 不推荐使用
5 懒汉式(线程安全,同步代码块)
class Singleton{
private static Singleton instance;
private Singleton(){}
public static Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
instance = new Singleton();
}
}
return instance;
}
}
不推荐使用
6 双重检查
代码实现:
class Singleton{
private static volatile Singleton instance;
private Singleton(){}
public static synchronized Singleton getInstance(){
if(instance == null){
synchronized(Singleton.class){
if(instance == null)
instance = new Singleton();
}
}
return instance;
}
}
优缺点:
- 线程安全
- 延迟加载
- 推荐使用
7 静态内部类
代码实现:
class Singleton{
private static volatile Singleton instance;
private Singleton(){}
private static class SingletonInstance{
private static final Singleton INSTANCE = new Singleton();
}
public static synchronized Singleton getInstance(){
return SingletonInstance.INSTANCE;
}
}
静态内部类特点:
- 加载外部类时,内部类不会自动加载,只有使用到内部类的时候内部类才会加载。
优缺点:
- 懒加载
- 线程安全
- 推荐使用
8 枚举
代码实现:
enum Singleton{
INSTANCE; //属性
public void sayOK(){
System.out.println("ok~");
}
}
优缺点:
- 借助枚举实现单例模式,不仅能避免多线程同步问题,而且还能放置反序列化重新创建新的对象
- 推荐使用