单例模式是一种创建型设计模式,它保证一个类仅有一个实例,并提供一个访问它的全局访问点。这种模式通常用于那些需要频繁创建和销毁的对象,例如数据库连接、线程池等。在Java中,可以通过私有构造函数、静态方法和双重检查锁定等方式实现单例模式。
本文目录导读:
在软件工程中,设计模式是一种解决特定问题的优秀解决方案,它们提供了一套经过验证的方法来解决常见的设计问题,单例模式是最常用的设计模式之一,它的主要目标是确保一个类只有一个实例,并提供一个全局访问点。
单例模式的定义
单例模式(Singleton Pattern)是一种常用的软件设计模式,在它的核心结构中只包含一个被称为单例的特殊类,通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
单例模式的实现方式
1、饿汉式(静态常量)
饿汉式是在类初始化时,已经自行把实例创造好(创建对象),不管之后是否需要使用,先占位再说,所以类加载比较早,不用担心线程同步问题,这种方式基于类加载机制惰性,天然的线程安全,但可能会造成内存的浪费。
public class Singleton { private static final Singleton INSTANCE = new Singleton(); private Singleton() {} public static Singleton getInstance() { return INSTANCE; } }
2、懒汉式(线程不安全)
懒汉式也叫延迟加载,顾名思义,该实例在第一次被使用时创建,这种方式基于 "按需生成" 的想法以避免实例化开销,首次调用时才实例化,但它不能保证线程安全。
public class Singleton { private static Singleton instance; private Singleton() {} public static Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
3、懒汉式(线程安全,同步方法)
这种方式和第二种方式本质相同,但是通过synchronized关键字保证在同一时间只能有一个线程获取到该实例,这样就解决了线程安全问题。
public class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
4、双重检查锁定(推荐)
这种方式同样使用了懒汉式的思路,但通过双重检查锁定机制既保证了懒加载,又保证了线程安全,只有第一次会同步,这就使得性能大大提高。
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; } }
单例模式的使用场景
1、创建一个对象需要消耗大量资源,且对象的创建次数有限,如数据库连接。
2、工具类对象,配置对象、读取磁盘文件的对象等。
3、系统中有一处对象需要频繁地创建和销毁。
单例模式的优缺点
优点:
1、在内存里只有一个实例,减少了内存开支,特别是当对象数量非常多时。
2、避免了大量的临时对象创建,降低了系统的内存压力。
3、允许对创建实例的过程进行控制。
缺点:
1、由于单例模式中没有抽象层,因此单例类的扩展有很大的困难。
2、滥用单例将带来一些负面问题,如程序的功能弱化,在某些情况下将导致程序逻辑错误,不利于数据封装和隐藏。
3、系统采用单例模式,不利于功能的扩展和维护。
单例模式的替代方案
1、原型模式:通过复制的方式创建新对象。
2、工厂方法模式:使用工厂方法代替直接实例化对象。
3、建造者模式:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。
4、依赖注入:通过外部依赖注入来构造对象。
5、享元模式:运用共享技术有效地支持大量细粒度的对象。
6、代理模式:为其他对象提供一种代理以控制对这个对象的访问。
7、注册模式:允许对象动态地注册到某个容器中。
8、适配器模式:将一个类的接口转换成客户希望的另一个接口。
9、桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
10、组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。
11、装饰器模式:动态地给一个对象添加一些额外的职责。
12、外观模式:为子系统中的一组接口提供一个一致的界面。
13、享元模式:运用共享技术有效地支持大量细粒度的对象。
14、代理模式:为其他对象提供一种代理以控制对这个对象的访问。
15、注册模式:允许对象动态地注册到某个容器中。
16、适配器模式:将一个类的接口转换成客户希望的另一个接口。
17、桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
18、组合模式:将对象组合成树形结构以表示“部分-整体”的层次结构。
19、装饰器模式:动态地给一个对象添加一些额外的职责。
20、外观模式:为子系统中的一组接口提供一个一致的界面。
单例模式是一种常用的设计模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点,单例模式有多种实现方式,包括饿汉式、懒汉式、懒汉式(线程安全,同步方法)和双重检查锁定,单例模式适用于创建对象需要消耗大量资源,且对象的创建次数有限的场景,单例模式也存在一定的缺点,如扩展困难、功能弱化等,在实际开发中,可以根据具体需求选择合适的设计模式。