`

单例模式("懒加载")性能优化方案

 
阅读更多

单例模式是23种设计模式之一,是比较简单的一种设计模式,它的目的是无论调用多少次,都返回同一个对象,它的特点是构造器私有化。

  它分为两种结构,一种是懒汉式的,一种是饿汉式的,它们各有优缺点,我们先从饿汉式看起,代码如下:

1
2
3
4
5
6
7
8
public class Single {
  private static Single single = new Single(); 
  private Single() { 
  }
   public Single getInstance() {
    return single;
  
}

通过上面的程序可以看出来虽然我们加载同一个对象的目的确实达到了,但当程序被加载的时候就会创建single这个对象,当这个类有多个这样的方法时,我们可能会用不到这个对象中大多数单例,就会造成对内存的浪费。所以就出现了懒汉式的单例模式,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
public class Single {
  private static Single single = null
  private Single() { 
  }
  
  public Single getInstance() {
    if(single==null){
      single = new Single();
    }
    return single;
  
}

这样,只有当我们真正调用这个对象时它才会被new出来,但是这样是存在问题的。

  当上面的第二段代码在第一次加载的时候有两个线程对其进行了调用,则会产生两个不同的对象,所以是线程不安全的,这时候就会想到给这个方法加个锁,加锁之后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
public class Single {
  private static Single single = null
  private Single() { 
  }
  
  public synchronized Single getInstance() {
    if (single == null) {
      single = new Single();
    }
    return single;
  
}

这样做确实做到了线程安全,但是当加锁这个方法里面要执行很多东西,调用这个方法花费的时间会很长,这样对服务器来说是致命的,因为这个方法如果某个线程一直调用的话,其它的线程是没有办法调的,服务器就阻塞了,那么升级后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Single {
  priate static Single single = null
  private Single() { 
  }
  
  public Single getInstance() {
    if (single == null) {
      synchronized (Single.class) {
        single = new Single();
      }
    }
    return single;
  }
}

仔细观察以后发现这样并没有锁住,当第一次同时有两个线程到达getInstance()方法if判断时,其中有一个肯定是阻塞的,当另外一个执行完以后,阻塞这个线程是不会再判断是否为空的,还是会创建一个对象的,这样又有多个对象被产生了,再对其进行升级,得到的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Single {
  private static Single single = null
  private Single() { 
  }
  
  public Single getInstance() {
    if (single == null) {
      synchronized (Single.class) {
        if (single == null) {
          single = new Single();
        }
      }
    }
    return single;
  }
}

这样就不会产生上面的问题,而且也只锁一次,因为第二次再执行这个方法时,会跳过if判断,直接返回single,不会再被锁,执行效率也会很高。

  但即使是这样,也还是有问题的,因为我们不能确定在内存中是先给对象赋值,还是先创建了这个对象,所以第二个程序有可能得到的是初始化一半了的对象,在jdk1.5之后,我们可以用volatile这个关键字来避免这种情况,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Single {
  private static volatile Single single = null
  private Single() { 
  }
  
  public Single getInstance() {
    if (single == null) {
      synchronized (Single.class) {
        if (single == null) {
          single = new Single();
        }
      }
    }
    return single;
  }
}

但是这种情况很少使用,我在这里只是为了学习一下,嘻嘻

 

分享到:
评论

相关推荐

    设计模式——单例模式

    为了解决懒汉式单例模式的性能问题,有几种优化策略: 1. **双检锁/双重校验锁(DCL,即 double-checked locking)** ```java public class Singleton { private volatile static Singleton instance; private ...

    三种工厂设计模式和两种单例模式

    饿汉单例模式是线程安全的,因为它在类加载时就完成了实例化,所以不会存在多个线程同时创建多个实例的情况。这种模式在多线程环境下性能较好,但可能导致不必要的内存占用。 2. **懒汉单例模式**:也称为延迟初始...

    单例模式介绍

    在Android开发中,单例模式应用广泛,尤其在管理全局资源、提供公共服务或优化性能时非常实用。下面我们将详细介绍六种常见的单例模式,并探讨在Android环境下如何应对反序列化安全问题。 1. 饿汉式单例(Static ...

    单例模式在实现飞机大战的源码.rar

    总结起来,单例模式在“飞机大战”游戏的源码中起到了至关重要的作用,它保证了游戏核心对象的唯一性,优化了资源管理,提高了游戏性能。通过深入理解和运用单例模式,开发者能够更好地设计和实现类似的游戏项目,...

    Java中的五种实现方法【单例模式】

    同时,随着Java技术的发展,枚举单例、基于依赖注入的单例等新型实现方式也逐渐流行,它们提供了更好的解决方案,避免了传统单例模式的一些问题。在阅读《浅议单例模式之线程安全.doc》文档时,可以深入理解这些细节...

    41丨单例模式(上):为什么说支持懒加载的双重检测不比饿汉式更优?1

    替代单例模式的解决方案可以考虑依赖注入框架,它们可以控制对象的生命周期和依赖关系,避免了单例模式的缺点,同时提供了更好的可测试性和灵活性。例如,Spring框架中的`@ Singleton`注解,可以在容器管理组件时...

    PHP5设计模式-单例模式

    4. **配置管理**:在大型项目中,配置文件可能很多,通过单例模式,可以确保所有的配置只加载一次,避免重复加载导致的性能问题。 ### 单例模式的优缺点 **优点**: 1. **节省资源**:对于开销大的对象,单例可以...

    IOS Swift3 四种单例模式详解及实例《PPT文档》

    懒加载单例在第一次使用时才进行初始化,提供最大的性能优化,但需要额外处理线程安全问题。 ```swift class Singleton { private static var _instance: Singleton? static var sharedInstance: Singleton {...

    ios-简易了解GCD的单例模式.zip

    2. **懒加载**:为了优化性能,单例通常采用懒加载策略,即首次使用时才进行初始化。 3. **生命周期**:单例的生命周期与应用程序相同,直到应用退出才会被销毁,因此它可以用于全局状态的管理。 GCD结合单例模式的...

    设计之模式之单例(Singleton)

    在软件设计模式中,单例...综上所述,单例模式是软件开发中的重要设计模式,它的应用和实现都需要根据具体场景谨慎选择,以达到最佳的代码设计和性能优化。了解并熟练掌握单例模式,有助于提升软件的可维护性和扩展性。

    浅析Java设计模式编程中的单例模式和简单工厂模式

    单例模式用于控制共享资源的唯一性,保证线程安全,并优化资源利用;而简单工厂模式则简化了对象创建过程,隔离了客户端与具体实现之间的耦合。理解并恰当运用这两种设计模式,可以提升代码的可读性和可维护性,对...

    JavaScript设计模式---单例模式详解【四种基本形式】

    // 输出true,证明两个引用指向同一对象总结:缓存单体模式确保了单例的唯一性,同时也优化了性能,只有第一次调用时才会执行数据库查询,之后的调用都直接从内存中的缓存获取,提高了效率。以上四种单例模式在...

    jdbc连接工具类 单例连接模式,进度1

    在本项目中,“jdbc连接工具类 单例连接模式,进度1”指的是创建了一个使用单例设计模式的JDBC连接工具类,以优化数据库连接的管理和复用,提高程序性能。下面我们将深入探讨这两个关键概念。 首先,让我们了解一下...

    android的电池内存优化方案+工具 +方法

    1. **减少对象创建**:频繁创建和销毁对象会增加内存开销,通过对象池、单例模式等手段减少内存分配。 2. **内存泄漏检测**:使用Memory Profiler工具检测并修复内存泄漏,确保对象及时释放。 3. **高效数据结构**...

    vue前端性能优化01

    在Vue.js前端开发中,性能优化是提升用户体验和应用...以上只是Vue.js前端性能优化的一部分策略,实践中还需要结合具体项目情况,选择合适的优化方案。不断学习和理解Vue.js的底层原理,有助于我们更好地进行性能调优。

    js代码-设计模式单例模式

    3. **缓存**:在需要频繁创建和销毁的对象中,单例模式可以避免频繁的创建和销毁过程,提高性能。 ### 实现单例模式的策略 在JavaScript中,有多种方式实现单例模式: #### 1. 模块模式 这是最简单的单例模式...

    python单例模式.zip_图形图像处理_Python_

    在“python单例模式.txt”文件中,可能详细阐述了如何在Python GUI编程中应用单例模式,包括如何创建单例,以及在图形图像处理中如何利用单例模式优化代码结构和性能。例如,可能涉及了如何使用`tkinter`或`PyQt`等...

    优化篇互联网架构及性能.rar

    4. **性能优化**:性能优化涵盖了代码优化、数据库查询优化、网络传输优化等多个方面。例如,通过减少冗余代码、使用高效算法、避免全局变量等方式优化代码;使用索引、优化SQL语句、减少数据库连接来提升数据库性能...

    review引发的有关于单例模式的思考

    单例模式是一种常用的软件设计模式,它的主要目的是确保一个类只有一个实例,并提供一个全局访问点。在Java等编程语言中,单例模式通常用于管理资源,如数据库连接、缓存服务或者线程池,因为它可以避免重复创建和...

    C#设计模式,单件模式,C#代码

    在软件设计领域,设计模式是一种经过验证的、通用的解决方案,用于解决常见的设计问题。C#作为.NET框架的主要编程语言,...通过研究提供的资源,你将能够更好地运用单例模式来优化你的代码,提高软件的可维护性和性能。

Global site tag (gtag.js) - Google Analytics