`

单例(Singleton)模式

阅读更多

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

要想控制一个类只被创建一个实例,那么首要的问题就是把创建实例的权限收回来,让类自己来负责创建自己类的实例,然后由这个类来提供外部可以访问这个类实例的方法,这就是单例模式的实现方法。

单例模式的结构和实现

单例模式的结构图
单例模式的结构图

Singleton:负责创建Singleton类自己的唯一实例,并提供一个getInstance的方法,来外部来访问这个类的唯一实例。

  1. 私有化构造方法
  2. 提供静态的获取实例的方法
  3. 定义存储实例的属性,因为要在静态方法中使用,因此要加上static修饰
  4. 实现控制实例的创建

示例代码

懒汉模式

所谓懒汉模式,既然懒,那么在创建对象实例时就不要着急,在马上要使用对象实例时才会创建,在装载对象时不会创建对象实例。

package com.liuhao.designpattern.singleton;

/**
 * 单例模式懒汉模式
 * 
 * @author liuhao
 * 
 *         2015年7月17日
 */
public class SingletonLazy {
    // 4. 定义一个变量来存储创建好的类实例
    // 5. 因为要在静态方法中使用,因此要加上static修饰
    private static SingletonLazy instance = null;

    // 1. 构造方法私有化,好在内部控制创建实例的数目
    private SingletonLazy() {
    }

    // 2. 定义一个方法为客户端提供类实例
    // 3. 这个方法需要定义成类方法,也就是
    public static SingletonLazy getInstance() {
        // 6. 判断存储实例的变量是否有值
        if (instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }

    private String singletonData;// 单例可以有自己的属性

    /**
     * 获取属性的值
     * 
     * @return 属性的值
     */
    public String getSingletonData() {
        return singletonData;
    }

    /**
     * 单例可以有自己的操作方法
     */
    public void singletonOperation() {

    }
}

饿汉模式

所谓饿汉模式,就是在创建对象实例时比较急,在装载类的时候就会创建对象实例。

package com.liuhao.designpattern.singleton;

/**
 * 单例模式饿汉模式
 * 
 * @author liuhao
 * 
 *         2015年7月17日
 */
public class SingletonHungry {
    // 4. 直装载类的时候就会创建对象实例,只创建一次
    private static SingletonHungry instance = new SingletonHungry();

    // 1. 构造方法私有化,好在内部控制创建实例的数目
    private SingletonHungry() {
    }

    // 2. 定义一个方法为客户端提供类实例
    // 3. 这个方法需要定义成类方法,也就是
    public static SingletonHungry getInstance() {
        // 5. 直接使用以及创建好的实例
        return instance;
    }

    private String singletonData;// 单例可以有自己的属性

    /**
     * 获取属性的值
     * 
     * @return 属性的值
     */
    public String getSingletonData() {
        return singletonData;
    }

    /**
     * 单例可以有自己的操作方法
     */
    public void singletonOperation() {

    }
}

其他

单例模式的范围

目前Java实现的单例是一个虚拟机范围的,因为装载类的功能是虚拟机的,所以一个虚拟机在通过自己的ClassLoader装载饿汉模式实现单例时就会创建一个类的实例。

因此如果一个虚拟机里面有很多个ClassLoader,而这些ClassLoader都装载某个类的话,就会产生多个实例。

单例模式的调用顺序

  • 懒汉模式
单例模式的调用顺序
单例模式的调用顺序
  • 饿汉模式
单例模式的调用顺序
单例模式的调用顺序

体现的一些思想

  • 延迟加载
    懒汉模式中,一开始没有加载所需的资源或者数据,一直等到马上就要使用了才加载,即所谓的“延迟加载”。

  • 缓存
    当某些资源或数据被频繁的使用,而且它们是存储在系统外部的(如数据库、硬盘),那么每次操作都要从数据库获取,速度会很慢,操作性能问题。

一个简单的方法就是把这些数据缓存到内存中,每次操作的时候先到内存里找,若有则直接使用;若果没有再获取它并设置到缓存中。

缓存是一种典型的空间换取时间的方案。

线程安全

  1. 不加同步的懒汉模式是线程不安全的。比如,有线程A、B同时调用getInstance方法,那就可能导致并发问题,如图。


    懒汉模式线程冲突
    懒汉模式线程冲突
  2. 如何实现懒汉模式的线程安全

    1. 加上关键字synchronized,如下
    public static synchronized SingletonLazy getInstance() {}
    
    1. 双重检查加锁。不是在每次进入getInstance时都需要同步,而是先不同步,进入方法后,先检查实例是否存在。如果不存在才进入下面的同步块,这是第一重检查。进入同步块后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。
      双重检查加锁机制的实现需要使用volatile关键字,被它修饰的变量的值将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能够正确的处理该变量。
      具体实现:
    public static SingletonVolatile getInstance() {
        // 检查实例是否存在,不存在则进入到同步块
        if (instance == null) {
            // 同步块,线程安全地创建实例
            synchronized (SingletonVolatile.class) {
                // 再次检查实例是否存在,不存在则真正的创建实例
                if (instance == null) {
                    instance = new SingletonVolatile();
                }
            }
        }
        return instance;
    }
    

    这种实现方式既可以实现线程安全,同时也不会对性能造成太大的影响。

  3. 饿汉模式是线程安全的。


作者:hoxis
链接:https://www.jianshu.com/p/24d2e6d9af3e
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
分享到:
评论

相关推荐

    深入浅出单例Singleton模式

    【深入浅出单例Singleton模式】 单例模式是一种在软件设计中常见的设计模式,它的核心目标是确保一个类只有一个实例,并提供一个全局访问点。在Java等面向对象编程语言中,单例模式常用于控制资源的共享,如全局...

    Qt qml Singleton 单例模式

    综上所述,Qt Qml的Singleton模式为全局共享对象提供了方便,使得在Qml环境中管理和访问同一对象变得简单。通过C++和Qml的有效结合,我们可以构建出高效且易于维护的应用程序。了解和熟练运用Singleton模式,对于...

    Singleton(单例模式)

    在Java应用中,单例对象能保证在一个...3、有些像交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了,只有使用单例模式,才能保证核心交易服务器独立控制整个流程。 CSDN代码的详细解释。

    单例模式 Singleton Pattern

    ### 单例模式 Singleton Pattern #### 概述 单例模式是一种常见的设计模式,属于创建型模式之一。这种模式的核心在于确保某个类只有一个实例存在,并且提供一个全局访问点来获取该实例。单例模式在Java开发中尤其...

    设计模式C++学习之单例模式(Singleton)

    单例模式是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。在C++中,实现单例模式有多种方法,我们将会深入探讨这一模式的原理、优缺点以及如何在实际编程中应用。 单例模式的核心在于...

    单例模式(singleton)

    单例模式是软件设计模式中的一种,它的核心思想是确保一个类在整个系统中只有一个实例,并提供一个全局访问点。在Java或类似编程语言中,单例模式常常被用来管理资源,比如数据库连接、线程池或者配置信息,因为这些...

     单例设计模式Singleton1

    单例设计模式Singleton1是Java设计模式中的一种创建型模式,指某个类采用Singleton模式,则在这个类被创建后,只可能产生一个实例供外部访问,并且提供一个全局的访问点。这个模式的核心知识点可以总结为三点: 1. ...

    Java 单例模式Singleton

    简单的单例模式举例Singleton 分为恶汉式 懒汉式

    单例模式Singleton(java源码)

    Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,确保用户无法通过new直接实例化它。除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()...

    单例 singleton txt

    单例模式(Singleton Pattern)是一种常用的软件设计模式,属于创建型模式之一。其主要目的是确保一个类只有一个实例,并提供一个全局访问点来访问该实例。这在某些情况下非常有用,比如系统中需要频繁创建后又销毁...

    单例设计模式的优缺点和设计思想

    单例设计模式是一种在软件工程中广泛使用的创建型设计模式,其核心思想是确保一个类仅有一个实例,并提供一个全局访问点。这种模式在多种场景下具有显著的优势,同时也存在一定的局限性和潜在的问题。 ### 单例设计...

    大话设计模式--Singleton(单例模式)

    单例模式是软件设计模式中的一种经典模式,它在许多场景下被广泛使用,尤其是在需要全局唯一实例的情况下。本文将深入探讨单例模式的概念、作用、实现方式以及其在实际编程中的应用。 单例模式的核心思想是确保一个...

    C++实现Singleton单例模式

    C++实现Singleton单例模式 本文档将详细介绍如何使用C++语言实现设计模式中的单例模式。单例模式是一种常用的设计模式,它可以确保一个类只能实例化一次。 单例模式的定义: 单例模式是一种创建型模式,它可以确保...

    Singleton pattern单例模式应用

    ### Singleton Pattern 单例模式应用详解 #### 一、单例模式概述 单例模式(Singleton Pattern)是一种常用的软件设计模式,在系统中确保某个类只有一个实例,并提供一个全局访问点。这种模式通常用于控制资源的...

    单例设计模式.pdf

    单例设计模式是一种在软件设计中广泛使用的设计模式,它属于创建型模式,其核心目标是确保类只有一个实例,并提供一个全局访问点。这个模式在Java中尤其常见,因为Java的垃圾回收机制允许对象长时间驻留在内存中,...

    Java的单例设计模式

    单例设计模式是软件设计模式中的经典模式之一,它的核心思想是确保一个类只有一个实例,并提供全局访问点。这种模式在Java中广泛应用于系统配置、线程池、缓存管理等场景,因为这些场景通常只需要一个共享的全局对象...

    singleton单例模式1

    "singleton单例模式1" 单例设计模式是软件设计模式中的一种,目的是确保某个类只能有一个实例,并提供一个全局的访问点来访问这个实例。 首先,单例模式的要点是:① 某个类只能有一个实例。构造器私有化。② 它...

    C#单例模式详解 C#单例模式详解C#单例模式详解

    单例模式是软件设计模式中的一种,它保证一个类只有一个实例,并提供一个全局访问点。在C#中,单例模式常用于管理共享资源或控制类的实例化过程,以提高性能、节约系统资源,特别是在整个应用程序生命周期内只需要一...

    单例设计模式源码和案例解析

    单例设计模式是一种常用的设计模式,它保证一个类只有一个实例,并提供一个全局访问点。在Java编程中,单例模式的应用广泛,例如控制资源的共享、管理配置信息等。本篇将深入解析单例设计模式的四种实现方式,并通过...

Global site tag (gtag.js) - Google Analytics