单例模式(Singleton pattern)
一个singleton 类是指这个类只能有一个实例,当系统只要求一个类的唯一实例时,我们就采用单例模式。要实现一个singleton类,我们首先要设置一个全局的点,以便其它类可以得到这个实例,其次很重要的一点是构造函数必须设定为私有,具体的实现通常有两种方式:饿汉式和懒汉式。从字面上去理解,懒汉式就是在不用的时候不去new这个实例,用到才去创建这个实例,它比较省空间,但是耗费时间;饿汗式是先提前new好实例,这样省时间但是耗费空间。
饿汉式:
public class Singleton {
//设置全局点,在类加载的时候就实例化
private static Singleton instence = new Singleton();
//私有的构造函数
private Singleton(){};
public static Singleton getInstence(){
return instence;
}
}
懒汉式:
public class Singleton {
//设置全局点,在类加载的时候仅仅声明一个空的对象
private static Singleton instance = null;
//私有的构造函数
private Singleton(){};
public static Singleton getInstence(){
if(instence == null)
instence = new Singleton();
return instence;
}
}
对于饿汉式的singleton是线程安全的,因为它在类加载的时候就实例化了一个对象,在高并发的多线程中,能访问到的也只有这一个实例。而对于懒汉式来讲,它并不是线程安全的,我们可以想象,在一个多线程的环境下,线程a判断instence为空时,因为创建对象需要时间,所以线程a等待实例创建,这时线程b正好也判断instence,而这时instence仍然为空,所以线程b也导致new了一个对象,这样就导致创建了多个对象。于是我们想到了使用同步锁,我们可以把同步锁加在一个方法上面,也可以加在一段代码上面,在这里我们为了减少系统性能消耗,我们仅在创建对象的时候进行同步就可以,为了保证只有第一个线程才可以创建对象,我们要在判断一次instence是否为空,改进后的代码如下:
public class Singleton {
//设置全局点,在类加载的时候仅仅声明一个空的对象
private static Singleton instance = null;
//私有的构造函数
private Singleton(){};
public static Singleton getInstence(){
if(instence == null)
synchronized(Singleton.class){
if(instence == null)
instence = new Singleton();
}
return instence;
}
}
***在这里我们用到了synchronized方法,如果对synchronized不了解,在其他文章中会详细介绍多线程中的同步机制。
但是我们如果仔细分析上面的例子,当创建对象的时候,jvm首先在栈中创建一个引用变量,然后再在堆中创建对象,中间是有时间间隔的,在这里,instence就是引用变量,jvm为它分配内存后,instence中的值已经不为空,这时如果另一个线程访问,它就会返回这个临时的值,因此用这种方法也不能解决线程安全问题。最终我们用了一个中间类解决了线程安全问题。
public class Singleton {
private Singleton() {}
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
当某对象第一次调用Singleton.getInstance()时,Singleton类被首次主动使用,jvm对其进行初始化(此时并不会调用Singleton()构造方法),然后Singleton调用getInstance()方法,该方法中,又首次主动使用了SingletonHolder类,所以要对SingletonHolder类进行初始化,初始化中,INSTANCE常量被赋值时才调用了Singleton的构造方法Singleton(),完成了实例化并返回该实例。当再有对象(也许是在别的线程中)再次调用Singleton.getInstance()时,因为已经初始化过了,不会再进行初始化步骤,所以直接返回INSTANCE常量即同一个Singleton实例。
分享到:
相关推荐
在实际开发中,我们需要根据项目需求和场景选择合适的单例实现方式。例如,如果应用对启动速度要求较高,可以选择饿汉式;如果需要延迟初始化,可以采用双重检查锁定或静态内部类方式;对于简单的单例,枚举方式也是...
根据提供的文件信息“Android源码设计模式解析与实战.PDF(完整版)”,本文将深入探讨其中的关键知识点,包括但不限于Android开发中常见的设计模式及其在实际项目中的应用案例。 ### Android设计模式概述 #### 设计...
《中文版_源码设计模式解析与实战.pdf》是一本专为Android开发者设计的进阶书籍,它深入探讨了设计模式在实际开发中的应用,并结合Android的源码进行了详细的解析。这本书不仅涵盖了基础的设计模式概念,还通过丰富...
- **Singleton模式**:确保一个类只有一个实例,并提供一个全局访问点。 - **Builder模式**:将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。 - **Prototype模式**:通过克隆已有的实例...
"iOS设计模式解析"这个主题涵盖了如何在Objective-C编程中应用这些模式来提高代码质量、可维护性和可扩展性。 设计模式可以分为三类:创建型、结构型和行为型。在iOS开发中,以下是一些关键的设计模式: 1. 单例...
《设计模式精解-GoF23种设计模式解析附C实现源码》这份资料深入浅出地介绍了软件工程领域著名的“Gang of Four”(GoF)所提出的23种设计模式,不仅提供了理论上的解析,还附带了具体的C语言实现源码,为读者提供了...
1. 创建型模式(Creational Patterns):这类模式主要处理对象的创建,包括单例模式(Singleton)、工厂方法模式(Factory Method)、抽象工厂模式(Abstract Factory)、建造者模式(Builder)和原型模式...
- 单例模式(Singleton):确保一个类只有一个实例,并提供一个全局访问点。 - 工厂方法模式(Factory Method):定义一个用于创建对象的接口,让子类决定实例化哪一个类。 - 抽象工厂模式(Abstract Factory):...
GoF(Gang of Four)23种设计模式是软件开发中的经典,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位专家在《设计模式:可复用面向对象软件的基础》一书中提出。这些模式为程序员提供了一种通用...
### 设计模式精解—GoF 23种设计模式解析及C++实现源码 #### 0. 引言 设计模式作为一种重要的面向对象设计工具,在软件开发中扮演着至关重要的角色。本文旨在深入解析GoF(Gang of Four,四人组)提出的23种设计...
- **1.3 Singleton模式**:单例模式确保一个类只有一个实例,并提供一个全局访问点。 - **1.4 Builder模式**:构建者模式允许你逐步构建复杂对象。该模式允许你使用相同的构建过程创建不同的表示。 - **1.5 ...
JavaEE设计模式是软件开发中的重要概念,它们是经过时间考验、被广泛接受的解决方案模板,用于解决..."JavaEE设计模式解析与应用"的主题涵盖了这些核心概念,将引导读者从理论到实践,提升其在JavaEE开发中的专业能力。
《Android源码设计模式解析与实战》这本书主要探讨了在Android开发过程中如何运用经典的设计模式来提高代码质量、可维护性和扩展性。本书不仅详细分析了Android系统内部使用的各种设计模式,还通过实战案例帮助读者...
设计模式解析(第2版)》以作者自身学习、使用模式和多年来为软件开发人员(包括面向对象技术老兵和新手)讲授模式的经验为基础撰写而成。首先概述了模式的基础知识,以及面向对象分析和设计在当代软件开发中的重要性,...
### 23种设计模式解析及其实现源码概览 #### 一、概述 《23种设计模式解析附实现源码(2nd Edition)》是一本深度解析设计模式的经典著作,书中不仅详尽地介绍了GoF所提出的23种设计模式,还提供了具体的实现代码,...
在软件开发领域,设计模式是一种经过验证的、通用的解决方案,用于解决常见的设计问题。GoF(Gang of Four)23种设计模式是软件工程中的经典,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides四位作者...