前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >设计模式(七):单例模式

设计模式(七):单例模式

作者头像
xujjj
发布2019-07-12 16:26:52
4000
发布2019-07-12 16:26:52
举报
文章被收录于专栏:IT界的泥石流

什么是单例模式

单例模式,是一种常用且简单的软件设计模式,属于创建型模式。应用单例模式的类在全局范围内必须只能有一个实例对象存在,且外部不需要实例化对象,就可以访问这个类的唯一实例对象。

注意:

  • 单例类只能有一个实例。
  • 单例类必须自己创建自己的唯一实例。
  • 单例类必须给外部提供访问唯一实例的方式。

应用场景与注意事项

在以下情况下可以考虑使用单例模式:

  • 系统只需要一个实例对象,如数据库连接池、网站计数器、网站缓存实例
  • 创建对象实例资源消耗太大。可以考虑使用单例模式全局只创建一个对象。
  • 客户调用类的单个实例只允许使用一个公共访问点,除了该公共访问点,不能通过其他途径访问该实例。

优点:

  • 全局只有一个实例,减少了内存的开销。
  • 避免对资源的多重占用。
  • 允许可变数目的实例

缺点:

  • 没有抽象层,不能继承,拓展难度大
  • 单例类职责多,与单一职责原则冲突

使用注意事项:

使用时不能用反射模式创建单例,否则会实例化一个新的对象 ;使用单例模式时注意线程安全问题

单例模式的几种实现场景

1、懒汉模式【线程不安全】

代码语言:javascript
复制
public class Singleton {
  private static Singleton instance;

  private Singleton() {}

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

这是比较简单的单例模式实现方式,采用延迟加载的方式,等到被使用时才实例化对象,资源利用率高。但是多线程下,会出现线程安全问题。

2、懒汉模式【线程安全】

代码语言:javascript
复制
public class Singleton {
  private static Singleton instance;

  private Singleton() {}

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

这种方式与第一种方式的区别在于 geInstance() 方法增加了 synchronized 关键词修饰,保证了线程安全问题,但是这样会影响程序性能。

3、饿汉模式【天生线程安全】

代码语言:javascript
复制
public class Singleton {
  private static Singleton instance = new Singleton();

  private Singleton() {}

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

这种方式在类装载的时候就完成实例化,避免了线程安全问题。但是如果程序从来没有使用这个实例就容易找到资源浪费。

4、双重检查锁模式【线程安全】(推荐)

代码语言:javascript
复制
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、静态内部类模式【线程安全】(推荐)

代码语言:javascript
复制
public class Singleton {

  private Singleton() {}

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

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

}

这种方式可以达到双重检查锁模式一样的性能,是线程安全的。它跟饿汉模式类似,两者都是采用了类装载的机制来保证初始化实例时只有一个线程。但是饿汉模式只要类被装载就会实例化,没有延迟加载的作用,而静态内部类方式在类被装载时并不会立即实例化,而是在需要使用实例的时候才会装载类,从而完成的实例化。

类的静态属性只会在第一次加载类的时候初始化,JVM保证了在类进行初始化时,别的线程是无法进入的,所以说是线程安全的。

6、枚举模式【线程安全】(推荐)

代码语言:javascript
复制
public enum Singleton {
  INSTANCE;
  public void doSomething() {
  }
}

JDK1.5后增加了枚举类型,我们可以通过枚举的方式简单地创建单例模式,它不仅能避免多线程同步问题,而且还自动支持序列化机制,防止反序列化重新创建新的对象,防止对象被多次实例化。

在实际工作中,我经常使用的是静态内部类模式。以上就是今天《单例模式》的讲解,良好的代码风格需要长期不断的积累学习。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT界的泥石流 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
文件存储
文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档