单例模式

设计模式中最简单的一种模式,即保证系统运行是,运行的类只有一个实例对象。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
单例模式注意事项:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给所有其他对象提供这一实例。

优点:

  1. 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
  2. 避免对资源的多重占用(比如写文件操作)。

缺点:

没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
代码实例:

  1. public class SingletonObject {
  2. //创建 SingletonObject 的对象
  3. private static SingletonObject instance = new SingletonObject ();
  4. //让构造函数为 private,这样该类就不会被实例化
  5. private SingletonObject (){}
  6. //获取唯一可用的对象
  7. public static SingletonObject getInstance(){
  8. return instance;
  9. }
  10. public void show(){
  11. System.out.println("这是一个单例模式的例子");
  12. }
  13. }
  14. public class SingletonPatternDemo {
  15. public static void main(String[] args) {
  16. //不合法的构造函数
  17. //编译时错误:构造函数 SingletonObject () 是不可见的
  18. //SingletonObject object = new SingletonObject ();
  19. //获取唯一可用的对象
  20. SingletonObject object = SingletonObject.getInstance();
  21. //调用方法
  22. object.show();
  23. }
  24. }

单例模式的几种实现方式

  • 饿汉式

最上面的例子,也是最常用的方式,缺点在于会产生很多垃圾对象,消耗内存。

  • 懒汉式 线程不安全

类中定义instance ,但是不实例化,等使用时在实例化,也就是所谓的懒加载。但是这种情况不适用于多线程,多线程的时候这就不是单例了,同时可能出现线程安全问题。

  1. demo
  2. public class Singleton {
  3. private static Singleton instance; // 先定义出instance,但是不实例化
  4. private Singleton (){}
  5. public static Singleton getInstance() {
  6. if (instance == null) {
  7. instance = new Singleton(); // 用到该类的时候才new出对象
  8. }
  9. return instance;
  10. }
  11. }
  • 懒汉式 线程安全
    和上面的模式相同只是在获取对象的时候用了synchronize关键字,保证线程安全
  1. public class Singleton {
  2. private static Singleton instance;
  3. private Singleton (){}
  4. public static synchronized Singleton getInstance() {
  5. if (instance == null) {
  6. instance = new Singleton();
  7. }
  8. return instance;
  9. }
  10. }
  • 双检锁/双重校验锁
    在懒汉式线程安全模式下,对事先定义的instance进行可见性操作,即加上volatile 关键字,保证,线程安全也保证对象可见,保证不会出现单例对象多例出现的情况
  1. public class Singleton {
  2. private volatile static Singleton singleton;
  3. private Singleton (){}
  4. public static Singleton getSingleton() {
  5. if (singleton == null) {
  6. synchronized (Singleton.class) {
  7. if (singleton == null) {
  8. singleton = new Singleton();
  9. }
  10. }
  11. }
  12. return singleton;
  13. }
  14. }
  • 枚举
    个人常用的类型,多种筛选类型时使用直观明了