单例模式(Singleton Pattern)是一个比较简单的模式。
定义:
确保某一个类只有一个实例,而且自动实例化并向整个系统提供这个实例。
通用类图:
通用代码:
Singleton类称为单例类,通过使用private的构造函数确保了在一个应用中只产生一个实例,并且是自行实例化的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
/**
*
线程安全的单例模式
*
饿汉式单例
*
@author Administrator
*
*/
public class Singleton
{
private static final Singleton
singleton = new Singleton();
private Singleton()
{
}
public static Singleton
getSingleton() {
return singleton;
}
public static void doSomething()
{
}
}
|
单例模式的优点:
- 由于单例模式在内存中只有一个实例,减少了内存开支,特别是一个对象需要频繁地创建、销毁时,而且创建或销毁时性能又无法优化,单例模式的优势就非常明显了。
- 由于单例模式只生成一个实例,所以减少了系统的性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后用永久驻留内存的方式来解决。
- 单例模式可以避免对资源的多重占用,例如一个写文件动作,由于只有一个实例存在内存中,避免对同一个资源文件的同时写操作。
- 单例模式可以在系统设置全局的访问点,优化和共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。
单例模式的缺点:
- 单例模式一般没有接口,扩展很困难,若要扩展,除了修改代码基本上没有第二种途径可以实现。
- 单例模式对测试是不利的。在并行开发环境中,如果单例模式没有完成,是不能进行测试的,没有接口也不能用mock的方式虚拟一个对象。
- 单例模式与单一职责原则有冲突。一个类应该只实现一个逻辑,而不关心它是否是单例的,是不是要单例取决于环境,单例模式把“要单例”和业务逻辑融合在一个类中。
单例模式的使用场景:
- 要求生成唯一序列号的环境;
- 在整个项目中需要一个共享访问点或共享数据,例如一个Web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的;
- 创建一个对象需要消耗的资源过多,如要访问IO和数据库等资源;
- 需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当然,也可以直接声明为static的方式)。
单例模式的注意事项:
1. 在高并发情况下,请注意单例模式的线程同步问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
/**
*
懒汉式单例
*
@author Administrator
*
*/
public class Singleton2
{
private static Singleton2
singleton = null ;
private Singleton2()
{
}
public static Singleton2
getSingleton() {
synchronized (singleton)
{
if (singleton
== null )
{
singleton
= new Singleton2();
}
}
return singleton;
}
}
|
如果不加synchronized进行控制,如果第一个线程A执行到singleton = new Singleton2(),但还没有获得对象,第二个线程B也在执行,执行到if (singleton == null)判断,那么线程B获得判断条件为真,于是继续运行下去,线程A和B都获得了对象,内存中就出现了两个对象。
建议使用饿汉式单例,那是线程安全的单例模式。
2. 需要考虑对象的复制情况。在Java中,若实现Cloneable接口,并实现了clone方法,则可以直接通过对象复制方式创建一个新对象,对象复制是不用调用类的构造函数的。
3. 注意JVM的垃圾回收机制,如果我们的一个单例对象在内存中长久不使用,JVM就认为这是一个垃圾对象,在CPU资源空闲的情况下该对象会被清理掉,下次再调用时就需要产生一个新对象。如果该对象作为有状态值的管理,则会出现状态恢复原状的情况,就会出现故障。
有两种方法可以解决该问题
1、由容器管理单例的生命周期
Java EE容器或者框架级容器(如Spring)可以让对象长久驻留内存。
2、状态随时记录
可以使用异步记录的方式,或者使用观察者模式,记录状态的变化,写入文件或写入数据库中,确保即使单例对象重新初始化也可以从资源环境获得销毁前的数据,避免应用数据丢失。
单例模式的扩展:
能产生固定数量实例的单例模式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
/**
*
能产生固定数量实例的单例模式
*
@author Administrator
*
*/
public class Singleton3
{
private static int maxNumOfSingleton
= 2 ;
private static ArrayList<Singleton3>
singletonList = new ArrayList<Singleton3>();
static {
for ( int i
= 0 ;
i < maxNumOfSingleton; i++) {
singletonList.add( new Singleton3());
}
}
private Singleton3()
{
}
public static Singleton3
getInstance() {
Random
random = new Random();
return singletonList.get(random.nextInt(maxNumOfSingleton));
}
}
|
分享到:
相关推荐
前言,UML建模技术,深入浅出UML类图,从招式与内功谈起——设计模式概述,面向对象设计原则,工厂三兄弟之简单工厂模式,工厂三兄弟之工厂方法模式,工厂三兄弟之抽象工厂模式,确保对象的唯一性——单例模式,...
优点:因为单例模式里面只有一个实例,避免了重复创建及回收实例,减少了内存的开销,提高了软件的性能,还可以避免资源的争用。 实现 饿汉式 所谓饿汉式就是,需要的实例提前创建好,需要用时就能够
设计模式之——单例模式单例的几种实现1. 懒汉单例模式2. synchronized 修饰的懒汉单例模式3. 双重检查锁定的单例模式4. 静态内部类实现单例模式5. 饿汉实现单例模式6. 饿汉变种实现单例模式7. 枚举实现单例模式...
如:IO处理,数据库操作等,由于这些对象都要占用重要的系统资源,所以我们必须限制这些实例的创建或始终使用一个公用的实例,这就是我们今天要介绍的——单例模式(Singleton)。 使用频率高 单件模式(Singleton...
2-4 单例模式的实用工程技术——从单例到多例,应用系统缓存的实现原理 2-5 工厂模式的定义场景与实现——子类延迟实现父类功能的软件结构 2-6 工厂模式的实用工程技术——IOC容器与工厂模式的应用 2-7 抽象工厂的...
目录: 前 言 第一部分 大旗不挥,谁敢冲锋——热身篇 第1章 单一职责原则 1.1 我是“牛”类,我可以担任多职吗 1.2 绝杀技,打破你的传统思维 1.3 我单纯,所以我快乐 1.4 最佳实践 ...附录:23个设计模式
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:...
第3章GoF-CreationalDesignPatterns创建型设计模式 23 3.1SimpleFactoryPattern(简单工厂模式) 24 3.1.1定义 24 3.1.2现实例子——国旗生产厂 26 3.1.3C#实例1——电子付款系统 26 3.1.4C#实例2——学校登录...
第3章GoF-CreationalDesignPatterns创建型设计模式 23 3.1SimpleFactoryPattern(简单工厂模式) 24 3.1.1定义 24 3.1.2现实例子——国旗生产厂 26 3.1.3C#实例1——电子付款系统 26 3.1.4C#实例2——学校登录...
(二) 确保对象的唯一性——单例模式 (三) 确保对象的唯一性——单例模式 (四) 确保对象的唯一性——单例模式 (五) 原型模式-Prototype Pattern 对象的克隆——原型模式(一) 对象的克隆——原型模式(二) ...
在本系统中,代理商类、可口可乐公司类和百事可乐公司类都使用到了代理模式,而且代理商类使用了懒汉式来实现单例模式,可口可乐公司类使用了饿汉式实现单例模式,而百事可乐类使用了双重检查锁来实现单例模式。...
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。 行为型模式,共十一种:...
单例模式: 而且自行实例化并向整个系统提供这个实 单例模式 单例模式确保某一个类只有一个实例, 例单例模式。单例模式只应在有真正的“单一实例”的需求时才可使用。 结构型模式 6、ADAPTER —在朋友聚会上碰到...
第一部分 设计模式初体验第1章 你好,设计模式1.1 这是一本什么书1.2 开始前的准备1.3 预备知识1.4 似曾相识的设计1.5 设计模式的起源——模型、视图和控制器1.5.1 在模型对象中封装数据和基本行为1.5.2 使用视图...
25.设计模式之单例模式 26.设计模式之构造函数模式 27.设计模式之建造者模式 28.设计模式之工厂模式 29.设计模式之装饰者模式 30.设计模式之外观模式 31.设计模式之代理模式 32.设计模式之观察者模式 33.设计模式之...
《设计模式》一书中给出了一种很不错的实现,定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。 单例模式通过类本身来管理其唯一实例,这种特性提供了解决问题的方法...
结构型模式:这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。 适配器模式(Adapter Pattern)桥接模式(Bridge Pattern)过滤器模式(Filter、Criteria Pattern)组合...
深入理解JavaScript系列(25):设计模式之单例模式 深入理解JavaScript系列(26):设计模式之构造函数模式 深入理解JavaScript系列(27):设计模式之建造者模式 深入理解JavaScript系列(28):设计模式之工厂...
单例模式也称为单件模式、单子模式,可能是使用广泛的设计模式。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出,GUI...
百度地图毕业设计源码 设计模式(Design Patterns)[原文地址:] ——可复用面向对象软件的基础 ...创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。 结构型模式,共七种:适配器