单例模式是一个简单的创建者类型的模式,必须保证在系统中最多只能有一个唯一的对象实例,有如下特点:
1、单例类必须保证最多只有一个实例;
2、必须由单例类自己创建唯一的实例;
3、单例类必须给其他所有对象提供其唯一的实例。
根据创建时间,单例模式又可以分为饥汉式和饱汉式两种,下面通过JAVA代码来分析二者的优缺点。
饥汉式单例模式:
/**
* HungerySingletonPatternTest
* 饥汉式单例模式
*/
public class HungerySingletonPatternTest{
private static final HungerySingletonPatternTest instance = new HungerySingletonPatternTest();
//构造函数声明为private,不能通过new关键字由外部生成实例对象
private HungerySingletonPatternTest(){
}
//只能通过该方法获取类的实例对象
public static HungerySingletonPatternTest getInstance(){
return instance;
}
}
饥汉式单例模式优点是简单切线程安全,但是缺点也很明显,在类加载时就要初始化单例类的对象,有可能在整个系统的生命周期内都用不到该单例对象,这样就造成了浪费,特别是该单例类的生成和持有要占很大资源的时候。
饱汉式单例模式改掉了饥汉式单例模式的缺点,代码如下:
/**
* FullSingletonPattern
* 饱汉式单例模式
*/
public class FullSingletonPatternTest{
private static final FullSingletonPatternTest instance = null;
//构造函数声明为private,不能通过new关键字由外部生成实例对象
private FullSingletonPatternTest(){
}
//只能通过该方法获取类的实例对象
public static synchronized FullSingletonPatternTest getInstance(){
if(instance == null){
new HungerySingletonPatternTest();
}
return instance;
}
}
饱汉式单例模式虽然改进了饥汉式单例模式的缺点,但是每次在获取单例对象时都要锁(Class Lock),在单线程或没够对单例类对象有竞争的应用场景下,加锁会造成不必要的性能损失。
对于饱汉式单例模式的缺点,有人提出了所谓的“双重检查锁”的饱汉式单例模式,代码如下:
/**
* DoubleCheckerSingletonPatternTest
* “双重检查锁”饱汉式单例模式
*/
public class DoubleCheckerSingletonPatternTest{
private static final DoubleCheckerPatternTest instance = null;
//构造函数声明为private,不能通过new关键字由外部生成实例对象
private DoubleCheckerSingletonPatternTest(){
}
//只能通过该方法获取类的实例对象
public static DoubleCheckerSingletonPatternTest getInstance(){
if(instance == null){
synchronized(DoubleCheckerSingletonPatternTest.class){
if(instance == null){
new DoubleCheckerSingletonPatternTest();
}
}
}
return instance;
}
}
但是“双重检查锁”的饱汉式单例模式,实际上不是线程安全的:由于编译器的优化,允许出现主存和线程工作内存数据不一致问题,这就是“DCL失效”的问题,并不能保证这个双重检查锁定习语有效。它偶尔会失败,而不是总失败。具体原因请参详
http://www.ibm.com/developerworks/cn/java/j-dcl.html。
JAVA语言提供内部静态类,我们可以基于内部静态类的特性,改进饱汉式单例模式,提供一种高效而安全的单例模式,代码如下:
/**
* StaticInnerClassSingletonPatternTest
* 基于内部静态类的单例模式
*/
public class StaticInnerClassSingletonPatternTest{
private StaticInnerClassSingletonPatternTest{}
//定义一个私有的内部静态类并在其中初始化外部单例对象
private static class SingletonHolder{
static final StaticInnerClassSingletonPatternTest INSTANCE = new StaticInnerClassSingletonPatternTest();
}
//只能通过该方法获取类的实例对象
public static StaticInnerClassSingletonPatternTest getInstance(){
return StaticInnerClassSingletonPatternTest.INSTANCE;
}
}
通过静态内部类的方式生成的单例模式,既保证了线程安全的,有保证了延迟加载。
在JDK发展到JDK 5.0之后,volatile + synchronized可以在保证内存模型的三个特性,即可见性、原子性和顺序性之外,对于被定义为volatile的变量,又禁用了volatile变量的重排序优化,就可以通过如下方式生成的单例模式,既保证安全性又兼顾延迟加载的功能,代码如下:
/**
* NewDoubleCheckerSingletonPatternTest
* volatile + synchronized的“双重检查锁”饱汉式单例模式
*/
public class NewDoubleCheckerSingletonPatternTest{
private static volatile NewDoubleCheckerSingletonPatternTest instance = null;
//构造函数声明为private,不能通过new关键字由外部生成实例对象
private NewDoubleCheckerSingletonPatternTest(){
}
//只能通过该方法获取类的实例对象
public static NewDoubleCheckerSingletonPatternTest getInstance(){
if(instance == null){
synchronized(NewDoubleCheckerSingletonPatternTest.class){
if(instance == null){
new DoubleCheckerSingletonPatternTest();
}
}
}
return instance;
}
}
分享到:
相关推荐
单例模式有多种实现方式,其中比较常见的有饿汉式、懒汉式、双重检查锁定等。 工厂设计模式是一种创建型设计模式,它的主要目标是将对象的创建和使用分离,使得代码更具有可维护性和可扩展性。该模式通常会定义一个...
实验五:单例模式.rar实验五:单例模式.rarjava设计模式
单例模式主要有懒汉式和饿汉式两种实现,饿汉式不会有线程安全的问题,但是提前构造对象占用了一定的资源,如果对内存要求较低的场景可以使用饿汉式实现;懒汉式应使用DCL机制来避免多线程竞争资源的问题,并且懒汉...
写在前面 分享一些设计模式的笔记。陆续整理,按照设计模式类型,创建型,结构型,行为型发布 博文会用通俗的话梳理一些自己的理解,结合开发中的实际场景, 理解不足小伙伴帮忙指正,虚心接受 ^_^ 傍晚时分
单例模式也称为单件模式、单子模式,可能是使用最广泛的设计模式。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出,...
本文实例讲述了JS 设计模式之:单例模式定义与实现方法。分享给大家供大家参考,具体如下: 良好的设计模式可以显著提高代码的可读性,降低复杂度和维护成本。笔者打算通过几篇文章通俗地讲一讲常见的或者实用的设计...
02_JavaSE面试题:单例设计模式
软件体系结构实验报告
单例模式的实现饿汉式懒汉式线程安全的懒汉式登记式单例模式的优缺点单例模式的优点单例模式的缺点 单例模式是23个模式中比较简单的模式,应用也非常广泛 什么是单例模式? 单例模式的定义: Ensure a class ...
设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段...
是http://blog.csdn.net/lxq_xsyu/article/category/1544127博客中java设计模式的源代码。下载前请先看《设计模式——单例模式》一文。
C++单例设计模式,单例模式 C++单例设计模式,单例模式
李建忠老师的设计模式-单例模式讲解,示例以C++编程语言呈现。
设计模式之单例模式 设计模式之单例模式 设计模式之单例模式
本文件主要内容是前端的三种设计模式:单例模式,发布-订阅模式,策略模式,以及浏览器的垃圾回收机制,适合已经学习完了js基础的小伙伴(js基础部分可以看我前面的专栏——js每日一学),感兴趣的小伙伴可以自行...
设计模式-单例模式 学习时候联系的代码,可以进行参考
java设计模式:单例模式,工厂模式,装饰模式等等
Java面试题包括但不限于: Java基础知识:语法、面向对象编程、...Java设计模式:单例模式、工厂模式、代理模式等。 网络编程:TCP/IP、HTTP、Web Services等。 数据库相关:SQL语句、数据库连接池、事务管理等。