Saul's blog Saul's blog
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)

Saul.J.Wu

立身之本,不在高低。
首页
后端
分布式
前端
更多
分类
标签
归档
友情链接
关于
GitHub (opens new window)
  • Java入门基础

    • 计算机常识

    • Java语言概述

    • 基本语法

    • 数组

    • 面向对象

      • 面向对象
      • 类和对象
      • 类的成员-属性
      • 类的成员-方法
      • 类的成员-构造器
      • 面向对象特性-封装
      • this关键字
      • package关键字
      • import关键字
      • 面向对象特征-继承
      • 方法的重写
      • 访问权限修饰符
      • super关键字
      • 子类对象实例化的全过程
      • 面向对象特征-多态
      • 强制类型转换
      • Object类
      • 包装类
      • static关键字
      • 单例设计模式
        • 概念
        • 设计模式总览
        • 实现单例模式
          • 饿汉式
          • 懒汉式
        • 单例模式优点
        • 应用场景
        • 推荐书籍
      • main方法
      • 类的成员-代码块
      • final关键字
      • 抽象类与抽象方法
      • 接口
      • 类的成员-内部类
    • 异常处理

  • Java核心基础

  • 设计模式

  • Web开发

  • SpringBoot

  • 微服务

  • Elasticsearch

  • 运维

  • 后端
  • Java入门基础
  • 面向对象
SaulJWu
2020-12-15

单例设计模式

# 概念

设计模式是**在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。**设计模免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我们用不同的棋谱。套路。

所谓类的例(Singleton)设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。

如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。

因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。

# 设计模式总览

单例模式只是设计模式的一种而已,其实还有很多设计模式:

创建型模式,共5种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共7种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共11种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

加上单例模式,设计模式一共有23种。

# 实现单例模式

如何实现单例模式?

有两种方式,一种是饿汉式,另一种是懒汉式。

# 饿汉式

1、新建一个类,私有化构造器

public class Bank {

    /**
     * 私有化构造器
     */
    private Bank() {

    }
}
1
2
3
4
5
6
7
8
9

2、内部创建类的对象

private static Bank instance = new Bank();
1

3、提供公共的静态方法返回类的对象

public static Bank getInstance() {
return instance;
}
1
2
3

完整代码:

public class Bank {

    /**
     * 私有化构造器
     */
    private Bank() {

    }

    /**
     * 内部创建类的对象
     */
    private static Bank instance = new Bank();

    /**
     * 提供公共的静态方法返回类的对象
     */
    public static Bank getInstance() {
        return instance;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

3、查看地址值是否一致,是否为唯一

Bank bank1 = Bank.getInstance();
Bank bank2 = Bank.getInstance();
System.out.println(bank1 == bank2);
1
2
3

结果返回true

# 懒汉式

1、私有化构造器

2、声明当前类的对象

3、提供公共的静态方法返回类的对象

public class Order {
    /**
     * 私有化类的构造器
     */
    private Order() {

    }

    /**
     * 声明当前类的对象
     */
    private static Order instance = null;

    /**
     * 提供公共的静态方法返回类的对象
     */
    public static Order getInstance() {
        if (instance == null) {
            instance = new Order();
        }
        return instance;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

测试一下

Order o1 = Order.getInstance();
Order o2 = Order.getInstance();
System.out.println(o1 == o2);
1
2
3

返回true

饿汉式vs懒汉式

饿汉式,类加载就创建类的对象。

懒汉式,去获取对象的时候,如果对象为空才去创建。

饿汉式:

好处:线程安全。

坏处:对象加载时间过长

懒汉式:

好处:延迟对象的创建。

坏处:目前这种写法,线程不安全。(到多线程内容时,去修改)

在程序角度来看,懒汉式要好一点,因为它相当于饿汉式延迟去创建对象,当外部需要的时候才去创建对象。

但是从并发角度来看,是饿汉式好一点,当多个线程进来的时候,懒汉式可能会发生多次创建对象的事情,而饿汉式不会发生这样的事情,因为饿汉式只有类加载的时候,创建一次对象,类只加载一次。

# 单例模式优点

由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。

举例:

java.lang.Runtime

image-20201215152716199

# 应用场景

单例模式应用场景

  • 网站的计数器,一般也是单例模式实现,否则难以同步。
  • 应用程序的日志应用,一般都使用单例模式实现,这一般是由于共享的日志文件一直处于打开状态,因为只能有一个实例去操作,否则内容不好追加。
  • 数据库连接池的设计一般也是采用单例模式,因为数据库连接是一种数据库资源。
  • 项目中,读取配置文件的类,一般也只有一个对象。没有必要每次使用配置文件数据,都生成一个对象去读取。
  • Application 也是单例的典型应用
  • Windows的Task Manager (任务管理器)就是很典型的单例模式。
  • Windows的Recycle Bin(回收站)也是典型的单例应用。在整个系统运行过程中,回收站一直维护着仅有的一个实例。

# 推荐书籍

  • 大话设计模式
  • 深入浅出设计模式
帮我改善此页面 (opens new window)
#单例模式#饿汉式#懒汉式#singleton#设计模式
上次更新: 2020/12/18, 12:50:58
static关键字
main方法

← static关键字 main方法→

最近更新
01
zabbix学习笔记二
02-28
02
zabbix学习笔记一
02-10
03
Linux访问不了github
12-08
更多文章>
Theme by Vdoing | Copyright © 2020-2022 Saul.J.Wu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式