单例模式

单例类,通过使用private的构造函数确保一个应用中只产生一个实例,并且是自行实例化。通用代码如下:

public class Singleton{
    private static final Singleton singleton = new Singleton();
    //限制产生多个对象
    private Singleton(){}
    //通过该方法获取实例对象
    public static Singleton getSingleton(){
        return singleton;
    }
    public static void doSomething(){
    }
}

单例模式的优缺点:

  • 由于单例在内存中只有一个实例,减少内存开支,特别是对象需要频繁创建和销毁时;
  • 当单例模式只产生一个对象,当对象的产生需要较多资源,比如读取配置文件、产生其他依赖对象时,可以使用单例模式减少性能开销;
  • 可以避免对资源的多重占用,例如一个写文件操作,使用单例,可以避免同时对文件的写操作;
  • 设置系统全局访问点,优化和共享资源访问,比如设计一个单例类,处理所有数据表的映射处理。

但是它也有一些缺点:

  • 单例类一般没有接口,扩展很困难,而且接口对单例模式来说也没有意义,它要求自行实例化,而接口和抽象类是不能实例化的。
  • 对于测试不利。
  • 单例模式与单一职责模式有冲突。类应该只实现单个逻辑,而不关心是否是单例,单例模式把“要单例”和业务逻辑融合到一个类中。

使用场景:

  • 要求生成唯一的序列号的环境;
  • 访问共享资源点或共享数据,例如一个web计数器,不用每次都刷新到数据库中,使用单例模式并确保线程安全;
  • 创建一个对象需要消耗的资源过多,比如访问IO或者创建数据库等资源;
  • 定义大量静态常量和静态方法的类,比如工具类。

使用注意事项:

在高并发环境下,上述通用代码不会产生多个实例,但如果使用下面的方式创建(懒汉模式),则会出现问题:

//线程不安全类,需要使用synchronize关键字等手段加以同步
public
class Singleton{ private static Singleton singleton = null; //限制产生多个对象 private Singleton{} public static Singleton getInstance(){ if(singleton == null){ singleton = new Singleton(); } return singleton; } }

其次,需要考虑对象的复制情况,在java中,对象默认不可复制,除非实现了Cloneable接口,并实现了clone()方法,则可以直接复制出一个新对象,并且不通过构造函数,即使是私有构造函数,这种情况唯一的办法是不要事先Cloneable接口。

原文地址:https://www.cnblogs.com/loveBolin/p/9671791.html