java设计模式之单例模式

 更新时间:2017年10月18日 10:53:37   作者:WAUANG  
这篇文章主要为大家详细介绍了java设计模式之单例模式,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

单例模式也叫做单肩模式,也是一种创建型模式,是我们日常开发中最常使用的一种设计模式,经常被用来封装一些工具类,例如数据库连接等。

单例模式的定义:

单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中一个类只有一个实例。即一个类只有一个对象实例

单例模式分为以下几种:
①饿汉单例模式
②懒汉单例模式
③IoDH单例模式
④枚举单例模式

下面我们一一的进行介绍:

1.首先是饿汉单例模式,顾名思义“饿汉”,代表急着“吃饭”(这里的饭应该是指的实例对象),所以很早就创建出来。不多说,上代码:

package singleton;

public class HungrySingletonP {
  private static HungrySingletonP instance=new HungrySingletonP();

  public HungrySingletonP(){}

  public static HungrySingletonP getInstance(){
    return instance;
  }
}

这段代码很形象的体现了饿汉模式。

这种方法在类加载的时候就已经实例化了(只创建唯一的实例),所以不存在线程上的一些问题。但是,也因为如此如果有太多的单例,且这些实例不经常使用那么久会造成对内存的浪费。

2.懒汉模式,同样什么叫做懒汉模式?一个懒惰的人,只有去吃饭的时候才会去刷碗(昨天用过的脏碗),即:只有当用到对象的时候才去创建对象,来上代码:

package singleton;

public class LasySingletonV1 {
  private static LasySingletonV1 instance;

  public LasySingletonV1(){}

  public static LasySingletonV1 getInstance(){
    if(instance==null){
      return new LasySingletonV1();
    }else
      return instance;
  }
}

上面的这段代码是懒汉模式,当我们不需要实例的时候,它不会创建实例,只有需要实例的时候,才会创建,节省空间。
但是,我们不推荐使用,因为我们原来的设计理念是:当需要的时候(并且instance为空)创建实例,当已经创建过后,如果还需要实例,则判断instance是否为空,因为前边已经创建过了,不为空,所以直接返回之前已经创建的实例。
以上的想法是很好的,但是它是线程不安全的。因为:当有多个线程同时调用这个方法时,因为同时判断实例为空,所以会创建很多个实例,这不符合单例模式的设计理念(一个类只有一个实例对象)。

所以我们需要对它进行改进,因为它会异步创建多个实例,多以我们很容易就能想到,在getInstance方法之前加上synchronized进行同步:

package singleton;

public class LasySingletonV2 {
  private static LasySingletonV2 instance;

  public LasySingletonV2(){}

  public synchronized LasySingletonV2 getInstance(){

    if(instance==null){
      return new LasySingletonV2();
    }else
      return instance;
  }
}

上面这样,就不会创建多个实例对象符合单例模式的概念。

但是上面这样的设计使得我们每次需要目标实例的时候都要排队等待,假设有很多线程都在调用这个getInstance方法,那么就会陷入很长时间的等待,大大降低的程序的效率。

所以我们还要对程序进行一定的修改,如果我们创建一个

package singleton;

public class LasySingletonV3 {
  private static LasySingletonV1 instance;

  public LasySingletonV3(){}

  public LasySingletonV3 getInstance(){
    if(instance==null){
      synchronized(LasySingletonV3.class){
        if(instance==null){
          return new LasySingletonV3();
        }
      }
    }
    return instance;
  }
}

以上的方法是懒汉模式的完整版本,我们来仔细分析一下:

当有多个线程第一次调用这个方法的时候,都满足instance为空,来到下一步,先获得锁的线程进入下一步继续判断是否为空,为空,然后创建实例返回实例。

没有获得锁的线程一直等待到获得锁的线程释放锁,当在等待的线程获得锁的时候进入下一步,还要进行判断instance是否为空,但是这个时候instance已经不为空了,因为前面的线程已经创建了实例,所以返回已经创建好的实例。

以上是第一批调用getInstance方法的线程,当后续的线程调用这个方法的时候就不用进行锁的获取了和释放了,因为第一步已经判断instance不为空,直接返回instance实例。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 举例讲解Java设计模式编程中Decorator装饰者模式的运用

    举例讲解Java设计模式编程中Decorator装饰者模式的运用

    这篇文章主要介绍了Java设计模式编程中Decorator装饰者模式的运用,装饰者模式就是给一个对象动态的添加新的功能,装饰者和被装饰者实现同一个接口,装饰者持有被装饰者的实例,需要的朋友可以参考下
    2016-05-05
  • Java 高精度的大数字运算方式

    Java 高精度的大数字运算方式

    这篇文章主要介绍了Java 高精度的大数字运算方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • SpringBoot参数验证10个技巧值得收藏

    SpringBoot参数验证10个技巧值得收藏

    Spring Boot提供了内置的验证注解,可以帮助简单、快速地对输入字段进行验证,例如检查 null 或空字段、强制执行长度限制、使用正则表达式验证模式以及验证电子邮件地址,那么在Spring Boot应用中如何做好参数校验工作呢,本文提供了10个小技巧感兴趣的朋友一起看看吧
    2023-08-08
  • 快速学习JavaWeb中监听器(Listener)的使用方法

    快速学习JavaWeb中监听器(Listener)的使用方法

    这篇文章主要帮助大家快速学习JavaWeb中监听器(Listener)的使用方法,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • 使用Spring AOP实现用户操作日志功能

    使用Spring AOP实现用户操作日志功能

    这篇文章主要介绍了使用Spring AOP实现了用户操作日志功能,功能实现需要一张记录日志的log表,结合示例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • 深入解析Java的设计模式编程中建造者模式的运用

    深入解析Java的设计模式编程中建造者模式的运用

    这篇文章主要介绍了深入解析Java的设计模式编程中建造者模式的运用,同时文中也介绍了建造者模式与工厂模式的区别,需要的朋友可以参考下
    2016-02-02
  • java实现音频转文本的实现步骤

    java实现音频转文本的实现步骤

    本文主要介绍了java实现音频转文本的实现步骤,可以通过使用一些现成的库或者API来实现,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧
    2024-05-05
  • Mybatis中ResultMap解决属性名和数据库字段名不一致问题

    Mybatis中ResultMap解决属性名和数据库字段名不一致问题

    我们Pojo类的属性名和数据库中的字段名不一致的现象时有发生,本文就详细的介绍一下Mybatis中ResultMap解决属性名和数据库字段名不一致问题,感兴趣的可以了解一下
    2021-10-10
  • Java解决线程安全的两种方式分享

    Java解决线程安全的两种方式分享

    这篇文章主要为大家详细介绍了Java中两种常用的解决线程安全的方式——Synchornized和Lock,文中的示例代码简洁易懂,快跟随小编一起学习起来吧
    2023-06-06
  • 带你快速搞定java多线程(3)

    带你快速搞定java多线程(3)

    这篇文章主要介绍了java多线程编程实例,分享了几则多线程的实例代码,具有一定参考价值,加深多线程编程的理解还是很有帮助的,需要的朋友可以参考下
    2021-07-07

最新评论