`

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

 
阅读更多

单例模式是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 ...

    线程安全的单例模式

    ### 线程安全的单例模式详解 #### 一、单例模式简介 单例模式(Singleton Pattern)是软件开发中最常用的创建型设计模式之一,它的主要目标是确保一个类只有一个实例,并提供一个全局访问点。单例模式在很多场景下...

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

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

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

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

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

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

    JAVA设计模式中的单例模式

    - 当需要频繁地创建和销毁同一个对象时,可以使用单例模式来优化性能。 - 当对象的实例需要被整个系统共享,且只允许存在一个实例时,如数据库连接、线程池、缓存等。 - 当需要对某个对象进行严格控制时,例如控制对...

    多线程单例模式并发访问

    - **懒汉式**:通过静态内部类或者双重检查锁定的方式来实现线程安全的懒加载单例模式,即在第一次使用时才初始化。 #### 十、线程安全的懒汉式单例 懒汉式单例在实现线程安全性时,通常采用双重检查锁定技术: ``...

    PHP5设计模式-单例模式

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

    JAVA单例模式的几种实现方法

    为了解决这个问题,可以采用“双重检查锁定”(Double-Checked Locking)的优化方案。 #### 三、登记式单例模式 登记式单例模式通常用于类似于Spring框架中的bean管理方式,即在单例类中维护一个容器或注册表,将...

    C#设计模式(1)——单例模式.pdf

    ### C#设计模式详解:单例模式 #### 引言 设计模式是在软件工程领域内被广泛采用的一种最佳实践,其目的在于提供通用...无论是基于线程安全考虑还是性能优化,单例模式都是一个值得深入研究和灵活运用的设计模式。

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

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

    java单例模式课程.pdf

    Java单例模式是一种设计模式,它允许类只有一个实例,并提供一...通过单例模式,我们可以在保证全局唯一性的同时,减少重复加载配置文件的开销,提高程序的性能。在实际开发中,应根据项目需求选择适合的单例实现方式。

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

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

    教会你如何用好单例及单例的定义

    ### 单例模式详解及其应用 #### 一、单例模式概述 单例模式是一种常用的软件设计模式,属于创建型模式之一。...理解单例模式的不同实现方式及其优缺点,有助于开发者根据实际情况选择最适合的方案。

    Java多线程-解决单例模式中的懒汉式的线程安全问题

    ##### 优化方案 - 使用内部类 通过使用内部类来实现懒汉式单例模式,可以避免显式地同步代码。 **示例代码**: ```java public class Singleton { // 私有化构造器 private Singleton() {} // 使用内部类来...

    设计之模式之单例(Singleton)

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

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

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

    Java性能优化实战视频全集

    - **SpringBoot性能优化策略**: 包括开启懒加载、使用异步编程模型等。 #### 七、性能优化过程方法与求职面经总结 - **优化流程**: 定义问题、评估现状、制定策略、实施优化、验证效果。 - **面试技巧**: 分享面试...

Global site tag (gtag.js) - Google Analytics