前言

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

单例模式

介绍:确保在一个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. CF894E Ralph and Mushrooms

    题目 一眼题. 缩点然后dp. 注意一下计算一条边经过无限次可以获得多少价值这个东西要用到平方和公式. \(\sum\limits_{i=1}^ni^2=\frac{i(i+1)(2i+1)}6\) ...

  2. c++ vector 使用注意事项

    1. 初始化 c++ 11以后新增了大括号{}的初始化方式,需要注意与()的区别,如: std::vector<int> vecTest1(5);         //初始化5个元素,每个 ...

  3. 实用且堪称神器的Chrome插件推荐(转)

    出处: http://tengj.top/2018/02/17/ggcj/ 前言 相信很多人都在使用 Chrome 浏览器,其流畅的浏览体验得到了不少用户的偏爱,但流畅只是一方面, Chrome 最大 ...

  4. 手把手 教你把H5页面打造成windows 客户端exe 软件

    序言: 好久没有更新博客了,最近在工作中碰到这种需求,由于没有做过,中间碰到好多坑,最后在一位贵人帮助的情况下,最终还是搞定了. 第一步,先安装 cefpython3 pip install cefp ...

  5. 使用consul

    eureka官方已经正式宣布:自2.0起不再维护该项目,并在github 项目wiki上放出了一段吓唬人的话: 大意就是:从2.x起,官方不会继续开发了,如果需要使用2.x,风险自负.但其实我觉得问题 ...

  6. markdown的日常使用

    # POI前端接口 ``` 描述: 项目poi接口 作者: X-Wolf 时间: -- ``` ------ [TOC] ------ ##声明 ### 请求地址 ``` DOMAIN/strateg ...

  7. RabbitMQ延迟队列插件安装

    RabbitMQ延迟队列插件安装 一.下载插件 下载地址:https://www.rabbitmq.com/community-plugins.html 二.把下载的插件放到指定位置 下载的文件为zi ...

  8. Qt Creator 4.9 发布

    Qt Creator 4.8中引入了语言服务器协议支持,允许Qt Creator通过利用此标准轻松支持更多编程语言,使IDE和其他编程工具可以轻松地获得通用编程语言支持的交换格式.使用Qt Creat ...

  9. IBM DS5020 管理口密码重置

    IBM DS5020 管理口密码重置 使用超级终端进行连接,输入回车,然后Ctrl+Break(有时需要多按几次),屏幕会出现设置波特率的提示: Send for shell access or ba ...

  10. 009-saltstack之salt-ssh的使用及配置管理LAMP状态的实现

    1.salt-ssh的使用 官方文档:https://docs.saltstack.com/en/2016.11/topics/ssh/index.html (1)安装salt-ssh [root@l ...