前言

上面的章节中,我们介绍了工厂模式,它是创建型模式的一种。本章我们将会介绍 单例模式 ,它也是创建型模式的一种。单例模式是我们比较常用的一个设计模式,也是最简单的一种设计模式。

单例模式

介绍:确保在一个jvm中某个类有且只有一个实例。

类图:

从上面的类图中,我们可以总结出以下几点:

  • 单例模式需要实现一个私有的构造函数,防止有外部的语句会实例化该类。
  • 单例模式需要定义一个静态成员变量,用来指向该类的唯一实例。
  • 单例模式需要定义一个静态成员方法,用来返回该类唯一的实例。

单例模式的实现

单例模式的实现方式有8种,下面让我们分别来看一看这几种实现方式的区别。

饿汉模式

代码:

public class Singleton {
private Singleton() {
    if (singleton != null) {
      throw new RuntimeException();
    }
  }
private static Singleton singleton = new Singleton();
public static Singleton initSingleton() {
return singleton;
}
}
  • 是否是懒加载:否
  • 是否线程安全:是
  • 优点:不用加锁,执行效率高。
  • 缺点:类加载时就初始化,浪费内存。

饿汉模式(静态代码块初始化)

代码:

public class Singleton {
private Singleton() {
    if (singleton != null) {
      throw new RuntimeException();
    }
  }
private static Singleton singleton;
static {
singleton = new Singleton();
}
public static Singleton initSingleton() {
return singleton;
}
}
  • 是否是懒加载:否
  • 是否线程安全:是
  • 优点:不用加锁,执行效率高。
  • 缺点:类加载时就初始化,浪费内存。

懒汉模式

import java.util.Objects;

public class Singleton {
private Singleton() {
    if (singleton != null) {
      throw new RuntimeException();
    }
  }
private static Singleton singleton;
public static Singleton initSingleton() {
if (Objects.isNull(singleton)) {
singleton = new Singleton();
}
return singleton;
}
}
  • 是否是懒加载:是
  • 是否线程安全:否
  • 优点:不用加锁,执行效率高,第一次调用时初始化,避免了浪费内存。
  • 缺点:非线程安全,多线程环境下,可能会产生多个实例。

懒汉模式(线程安全)

import java.util.Objects;

public class Singleton {
private Singleton() {
    synchronized(Singleton.class) {
      if (Objects.nonNull(singleton)) {
        throw new RuntimeException();
      }
    }
  }
private static Singleton singleton;
public static synchronized Singleton initSingleton() {
if (Objects.isNull(singleton)) {
singleton = new Singleton();
}
return singleton;
}
}
  • 是否是懒加载:是
  • 是否线程安全:是
  • 优点:第一次调用时初始化,避免了浪费内存。
  • 缺点:实现了synchronized方法,会影响执行效率。

懒汉模式(同步代码块)

import java.util.Objects;

public class Singleton {
private Singleton() {
    synchronized(Singleton.class) {
      if (Objects.nonNull(singleton)) {
        throw new RuntimeException();
      }
    }
  }
private static Singleton singleton;
public static Singleton initSingleton() {
if (Objects.isNull(singleton)) {
synchronized (Singleton.class) {
singleton = new Singleton();
}
}
return singleton;
}
}
  • 是否是懒加载:是
  • 是否线程安全:否
  • 优点:第一次调用时初始化,避免了浪费内存。
  • 缺点:虽然实现了synchronized代码块,但是如果有多个线程同时实例化,那么有可能会产生多个实例。

双重检查模式

import java.util.Objects;

// 不能加Serializable,防止反序列化创建对象
public class Singleton {
private Singleton() {
    // 防止反射创建对象
    if (Objects.isNull(singleton)) {
      synchronized (Singleton.class) {
        if (Objects.isNull(singleton)) {
          singleton = this;
        } else {
          throw new RuntimeException();
        }
      }
    } else {
      throw new RuntimeException();
    }
  }
private static volatile Singleton singleton;
public static Singleton initSingleton() {
if (Objects.isNull(singleton)) {
synchronized (Singleton.class) {
if(Objects.isNull(singleton)) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
  • 是否是懒加载:是
  • 是否线程安全:是
  • 优点:第一次调用时初始化,避免了浪费内存。
  • 缺点:暂无

静态内部类

public class Singleton {
private Singleton() {
    if (Objects.nonNull(singleton)) {
      throw new RuntimeException();
    }
  }
public static Singleton initSingleton() {
return SingletonInstance.singleton;
} public static class SingletonInstance {
private static Singleton singleton = new Singleton();
}
}
  • 是否是懒加载:是
  • 是否线程安全:是
  • 优点:第一次调用时初始化,避免了浪费内存,效率高。
  • 缺点:暂无

枚举

public enum Singleton {
INSTANCE;
}
  • 是否是懒加载:是
  • 是否线程安全:是
  • 优点:第一次调用时初始化,避免了浪费内存,效率高。
  • 缺点:暂无

[design pattern](7) Singleton的更多相关文章

  1. Java Design Pattern(Factory,Singleton,Prototype,Proxy)

    一.Factory 设计模式: the most common pattern,create a new object ,eg. A a=new A();工厂模式的好处:工厂模式可以做到把创建对象单独 ...

  2. Learning JavaScript Design Patterns The Singleton Pattern

    The Singleton Pattern The Singleton pattern is thus known because it restricts instantiation of a cl ...

  3. Design Pattern —— Singleton

    Design Pattern —— Singleton   强力推荐枚举和类级内部类方式实现单例模式 单例模式是开发中非常常用的一种模式,简单的说,我们希望一个类永远都只有一个对象. 主要有两个用途: ...

  4. [Design Pattern] Singleton Pattern 简单案例

    Singleton Pattern, 即单例模式,用于获取类的一个对象,该对象在整个应用中是其类的唯一对象.单例模式属于创建类的设计模式. SingleObject 作为单例类,内含了一个静态私有的 ...

  5. python singleton design pattern super() 多继承

    python  singleton design pattern decorate baseclass metaclass import module super() 一.A decorator de ...

  6. 说说设计模式~大话目录(Design Pattern)

    回到占占推荐博客索引 设计模式(Design pattern)与其它知识不同,它没有华丽的外表,没有吸引人的工具去实现,它是一种心法,一种内功,如果你希望在软件开发领域有一种新的突破,一个质的飞越,那 ...

  7. 设计模式(Design Pattern)系列之.NET专题

    最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...

  8. [转]Design Pattern Interview Questions - Part 4

    Bridge Pattern, Composite Pattern, Decorator Pattern, Facade Pattern, COR Pattern, Proxy Pattern, te ...

  9. [转]Design Pattern Interview Questions - Part 1

    Factory, Abstract factory, prototype pattern (B) What are design patterns? (A) Can you explain facto ...

随机推荐

  1. (5.1.5)引擎管理——多服务器管理之中央管理服务器(CMS)

    关键词:中央管理服务器,CMS,多服务器管理 中央管理服务器 -[1]打开 视图->已注册的服务器 [2]注册中央管理服务器 右击中央管理器->注册中央管理服务器 这里输入IP.主机名都可 ...

  2. python 传址 与传值(暂时保存,后续做分类)

    # python 传址 与 传值 # 定义一个函数 用于将 list 下标为2的数据加100 并进行打印 该list def test1(list): list[2]+=100 print(list) ...

  3. Vue中使用fullpage.js

    Vue中使用fullpage.js:https://blog.csdn.net/weixin_34184158/article/details/88672739

  4. PythonDay15

    第十五章装饰器_递归 今日内容 带参数装饰器 多个装饰器修饰一个函数 递归 带参数的装饰器 # 判断argv,当登录不同的网页,会有不同的装饰效果def auth(argv):   def warpp ...

  5. SparkML之推荐算法ALS

    参考: SparkML之推荐算法(一)ALS --有个比较详细的讲解,包含blocks使用. Spark ALS源码总结 //TODO 源码,集群尝试.研究blocks使用原理及作用. 官方解释:nu ...

  6. vue-cli 2.* 中导入公共less文件

    在新版的Vue CLI 3中,如何导入公共less文件在文档里已经描述的很清楚了,但是在2.*的版本中,我没有查到相关的办法,网友的办法又相当复杂,于是我推荐给大家一个很简单的办法. 首先,会用到we ...

  7. 解决 SQLPlus无法登陆oracle,PLSql可以登陆,报错ORA-12560

    使用Oracle 11g 64位服务器,安装64位.32位客户端,出现SQLPlus无法连接数据库,PLSql可以连接问题. 网上查了很多,都不能解决问题,在下面提供一种. 环境变量 右击计算机属性- ...

  8. Flask开发系列之模板

    Flask开发系列之模板 本文对<FlaskWeb开发:基于python的Web应用开发实战>模板一节做的总结. Jinja2模板引擎 模板 模板是一个包含响应文本的文件,其中包含用占位变 ...

  9. random 方法 生成随机数

    Math.random() 生成 大于等于0.0 且小于 1.0 的double 型随机数 ( 0.0 <= Math.random() < 1.0 ) 可以使用它便携简单了表达式,生成任 ...

  10. Java函数优雅之道

    https://www.cnblogs.com/amap_tech/p/11320171.html 导读 随着软件项目代码的日积月累,系统维护成本变得越来越高,是所有软件团队面临的共同问题.持续地优化 ...