单例模式的定义 (单例模式两个基本要点)
本文目录导航:
单例模式的定义
单例模式最初的定义出现于《设计模式》(艾迪生维斯理, 1994):“保证一个类仅有一个实例,并提供一个访问它的全局访问点。
”Java中单例模式定义:“一个类有且仅有一个实例,并且自行实例化向整个系统提供。
”单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例。
特点:1、一个类只能有一个实例;2、自己创建这个实例;3、整个系统都要使用这个实例。

设计模式之单例模式
单例设计模式理解起来非常简单。
一个类只允许创建一个对象(或者实例),那这个类就是一个单例类,这种设计模式就叫单例模式。
下面的示例中如果每个类都创建一个 Logger 实例,就可能造成日志内容被覆盖的情况。
如果有些数据在系统中只应保存一份,那就比较适合设计为单例类。
比如,配置信息类,全局 ID 生成器等。
要实现一个单例,我们要考虑以下几点:
懒汉式相对于饿汉式的优势是「支持延迟加载」 。
但缺点也很明显,因为使用了 synchronized 关键字导致这个方法的「并发度很低」 。
如果这个单例类偶尔会被用到,那这种实现方式还可以接受。
但是,如果频繁地用到,就会导致性能瓶颈,这种实现方式就不可取了。
这是一种既支持延迟加载、又支持高并发的单例实现方式。
在 java1.5 以下 instance = new Singleton(); 有指令重排问题,需要给 instance 成员变量加上 volatile 关键字,java1.5 之后不会再这个问题。
这种方式利用了 Java 的静态内部类,有点类似饿汉式,但又能做到了延迟加载。
当外部类 Singleton 被加载的时候,并不会创建 SingletonHolder 实例对象。
只有当调用 getInstance() 方法时,SingletonHolder 才会被加载,这个时候才会创建 instance。
insance 的唯一性、创建过程的线程安全性,都由 JVM 来保证。
所以,这种实现方法既保证了线程安全,又能做到延迟加载。
这是一种最简单的实现方式,基于枚举类型的单例实现。
这种实现方式是通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。
上面的单例类对象是进程唯一的,一个进程只能有一个单例对象。那如何实现一个线程唯一的单例呢?
假设 IdGenerator 是一个线程唯一的单例类。
在线程 A 内,我们可以创建一个单例对象 a。
因为线程内唯一,在线程 A 内就不能再创建新的 IdGenerator 对象了,而线程间可以不唯一,所以,在另外一个线程 B 内,我们还可以重新创建一个新的单例对象 b。
我们通过一个 ConcurrentHashMap 来存储对象,其中 key 是线程 ID,value 是对象。
这样我们就可以做到,不同的线程对应不同的对象,同一个线程只能对应一个对象。
实际上,Java 语言本身提供了 ThreadLocal 工具类,可以更加轻松地实现线程唯一单例。
单例模式简介
单例模式是设计模式中极为基础且简单的一种模式。
其核心目标在于确保某个类在其整个生命周期中,仅能存在一个实例。
单例模式的实现方式多种多样,通常基于以下原理:通过静态方法限制对象的创建,进而确保全局范围内只有一个实例存在。
在实际编程中,开发者常采用“私有构造函数 + 静态方法”的模式来实现单例。
具体而言,单例类中包含一个私有静态实例变量,用于存储唯一的单例实例。
同时,单例类提供一个静态方法供外部调用,该方法会返回实例变量中存储的单例实例。
当客户端调用静态方法获取单例实例时,如果实例变量中尚未存在实例,则该方法会创建一个新实例并存入实例变量中;若实例变量中已存在实例,则直接返回已有的实例。
这种实现方式确保了全局范围内,单例类的实例数量始终为1,进而实现了单例模式的目的。
单例模式的实现原理与应用实例,可以进一步归纳为以下几点:1. **私有构造函数**:确保外部无法直接通过构造函数创建实例,限制了实例的创建权限。
2. **静态方法**:作为获取单例实例的唯一途径,保证了单例的全局唯一性。
3. **实例变量**:存储单例实例,确保了全局范围内实例的唯一性。
4. **实例检查与创建**:通过检查实例变量中是否已存在实例,决定是返回已有实例还是创建新实例。
单例模式的应用场景多样,常见于需要全局共享资源、管理全局配置、实现事件监听等需求的场景中。
它简化了代码结构,提高了程序的可读性和维护性。
单例模式是一种常用的软件设计模式。
在它的核心结构中只包含一个被称为单例类的特殊类。
通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。
如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。