Skip to content

单例模式

介绍

单例设计模式是创建型模式,是对某个类只能存在一个对象实例,并且该类提供一个获取其对象实例的方法。通常,出于节省内存资源的考虑会使用单例设计模式

分类

单例模式有八种方式:

  1. 饿汉式(静态常量)
  2. 饿汉式(静态代码块)
  3. 懒汉式(线程不安全)
  4. 懒汉式(同步方法)
  5. 懒汉式(同步代码块)
  6. 双重检查
  7. 静态内部类
  8. 枚举

1. 饿汉式(静态常量)

java
// 饿汉式(静态变量)
class Singleton {
    // 构造方法私有化,不能在外部实例化
    private Singleton() {
    }

    // 创建实例对象
    private final static Singleton instance = new Singleton();

    // 返回实例对象
    public static Singleton getInstance() {
        return instance;
    }
}

优点:在类加载的时候就完成了实例化,避免了线程同步问题

缺点:没有实现懒加载

2. 饿汉式(静态代码块)

java
// 饿汉式(静态代码块)
class Singleton {
    // 构造方法私有化,不能在外部实例化
    private Singleton() {
    }

    private static Singleton instance;

    // 创建实例对象
    static {
        instance = new Singleton();
    }

    // 返回实例对象
    public static Singleton getInstance() {
        return instance;
    }
}

优点:静态代码块里面的代码在类加载时就会执行,此时已经完成了实例化,避免了线程同步问题

缺点:没有实现懒加载

3. 懒汉式(线程不安全)

java
// 懒汉式(线程不安全)
class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

优点:实现了懒加载

缺点:线程不安全。单线程的情况下可以使用

4. 懒汉式(同步方法)

java
// 懒汉式(同步方法)
class Singleton {
	private static Singleton instance;

	private Singleton() {
	}

	public static synchronized Singleton getInstance() {
		if (instance == null) {
			instance = new Singleton();
		}
		return instance;
	}
}

优点:解决了线程不安全问题

缺点:效率低,synchronized锁住了整个方法,每次访问该方法,都会锁住整个方法,但是,instance实例在第一次访问的时候就已经实例化,后续只需要直接返回,没有线程安全的问题,也就不需要每次都锁住整个方法,导致方法的效率降低

5. 懒汉式(同步代码块)

java
// 懒汉式(同步代码块)
class Singleton {
    private static Singleton instance;

    private Singleton() {
    }

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                instance = new Singleton();
            }
        }
        return instance;
    }
}

优点:相比懒汉式(同步方法),效率有了一定的提高

缺点:线程不安全

6. 双重检查

java
// 双重检查
class Singleton {
	private static volatile Singleton instance;

	private Singleton() {
	}

	public static Singleton getInstance() {
		if (instance == null) {
			synchronized (Singleton.class) {
				if (instance == null) {
					instance = new Singleton();
				}
			}
		}
		return instance;
	}
}

优点:加入双重检查代码,解决线程安全问题, 同时解决懒加载问题,同时解决了效率问题

7. 静态内部类

java
// 静态内部类
class Singleton {
	private Singleton() {
	}

	private static class SingletonInstance {
		private static final Singleton INSTANCE = new Singleton();
	}

	public static synchronized Singleton getInstance() {

		return SingletonInstance.INSTANCE;
	}
}

优点:通过类加载机制解决了线程安全问题,在Singleton类被装载时并不会立即实例化,而是在需要实例化,实现了懒加载的效果

8. 枚举

java
// 枚举
enum Singleton {
	INSTANCE;

	public static Singleton getInstance() {
		return INSTANCE;
	}
}

优点:避免了线程安全问题,还能防止反序列化重新创建新的对象