唐宋元明清 唐宋元明清
首页
  • 基础

    • Java基础
  • 工具

    • hutool
    • commons
  • 框架

    • Spring Boot相关
  • 设计模式

    • 设计模式入门
  • Hadoop

    • Hadoop分布式搭建
    • Hadoop高可用搭建
    • 集群端口
    • 代码demo
  • Zookeeper

    • Zookeeper集群搭建
  • Hive

    • Hive集群搭建
    • Hive相关
    • HSQL
  • Kafka

    • Kafka集群搭建
  • HBase

    • HBase集群搭建
    • HBase基础学习
  • Spark

    • Spark环境搭建
    • Spark相关知识
  • Flink

    • Flink环境搭建
    • Flink学习
  • Flume

    • Flume安装配置
    • Flume高可用集群安装
    • Flume相关学习
  • Sqoop

    • Sqoop安装配置
    • Sqoop使用
  • 其他

    • docker
  • Oracle

    • Oracle相关知识杂记
    • 系统函数篇
    • 与MySQL语法区别
  • MySQL

    • MySQL知识点
  • Python

    • Python简单语法
    • Python操作Office
    • Python类库学习
    • Python爬虫
  • Shell

    • Shell基础
    • Shell命令行
  • Scala

    • 语法学习
  • 正则表达式

    • 正则基础
  • 调度

    • 调度工具
  • 前端

    • 前端相关
  • 杂记

    • 常用工具或网站
    • 琐碎知识
  • 摘录

    • 摘录
GitHub (opens new window)
首页
  • 基础

    • Java基础
  • 工具

    • hutool
    • commons
  • 框架

    • Spring Boot相关
  • 设计模式

    • 设计模式入门
  • Hadoop

    • Hadoop分布式搭建
    • Hadoop高可用搭建
    • 集群端口
    • 代码demo
  • Zookeeper

    • Zookeeper集群搭建
  • Hive

    • Hive集群搭建
    • Hive相关
    • HSQL
  • Kafka

    • Kafka集群搭建
  • HBase

    • HBase集群搭建
    • HBase基础学习
  • Spark

    • Spark环境搭建
    • Spark相关知识
  • Flink

    • Flink环境搭建
    • Flink学习
  • Flume

    • Flume安装配置
    • Flume高可用集群安装
    • Flume相关学习
  • Sqoop

    • Sqoop安装配置
    • Sqoop使用
  • 其他

    • docker
  • Oracle

    • Oracle相关知识杂记
    • 系统函数篇
    • 与MySQL语法区别
  • MySQL

    • MySQL知识点
  • Python

    • Python简单语法
    • Python操作Office
    • Python类库学习
    • Python爬虫
  • Shell

    • Shell基础
    • Shell命令行
  • Scala

    • 语法学习
  • 正则表达式

    • 正则基础
  • 调度

    • 调度工具
  • 前端

    • 前端相关
  • 杂记

    • 常用工具或网站
    • 琐碎知识
  • 摘录

    • 摘录
GitHub (opens new window)
  • Java相关知识
  • 基础

    • Java基础
    • Java扩展
  • 工具

    • hutool工具包
    • Commons类库
    • SQL解析工具
  • 框架

    • Spring Boot相关
  • 设计模式

    • 设计模式入门
    • 策略模式
    • 观察者模式
    • 装饰者模式
    • 工厂模式
    • 单例模式
      • 单例模式(Singleton)
        • 问题提出
        • 经典单例模式
        • 类图
        • 代码
        • 解决多线程问题
        • 1. 加 synchronized 锁
        • 2. 饿汉式单例
        • 3. 懒汉式单例(双重检查加锁)
        • 要点
    • 命令模式
    • 适配器模式与外观模式
    • 模板方法模式
    • 迭代器与组合模式
    • State 模式
    • 代理模式
  • Java相关
  • 设计模式
Ai
2022-07-17
目录

单例模式

# 单例模式(Singleton)

单例模式 确保一个类只有一个实例,并提供一个全局访问点。

# 问题提出

问题:有些对象我们只需要一个。比如线程池(threadpool)、缓存(cache)、对话框、处理偏好设置和注册表(registry)的对象、日志对象、驱动程序对象等。

Java 静态变量可以保证全局只有一个实例,但是会有缺点:必须一开始就创建好对象,

# 经典单例模式

# 类图
# 代码

问题:在多线程的情况下会出现问题

public class ChocolateBoiler {
    private boolean empty;   // 锅炉是否是空的
    private boolean boiled;  // 是否煮沸过
    private static ChocolateBoiler chocolateBoiler;

    private ChocolateBoiler() {
        empty = true;
        boiled = false;
    }

    public static ChocolateBoiler getInstance() {
        if (null == chocolateBoiler) {
            chocolateBoiler =  new ChocolateBoiler();
        }
        return chocolateBoiler;
    }

    public void  fill() {
        if (isEmpty()) {
            empty = false;
            boiled = false;
            // 在锅炉里填充巧克力和牛奶的混合物
        }
    }

    private boolean isEmpty() {
        return empty;
    }
}

# 解决多线程问题

# 1. 加 synchronized 锁

给 getInstance() 方法加 synchronized 锁,缺点是会降低性能。

# 2. 饿汉式单例

在JVM加载类时立刻实例化对象,后面调用 getInstance() 方法时直接返回实例就可以。

public class Singleton() {
  private static Singleton uniqueSingleton = new Singleton();

  private Singleton() {}

  public static Singleton getInstance() {
    return uniqueSingleton;
  }
}
# 3. 懒汉式单例(双重检查加锁)

利用双重检查加锁(double-checked locking),首先检查是否实例已经创建了,如果尚未创建,“才”进行同步。这样一来,只有第一次会同步,这正是我们想要的。

volatile关键字是java提供的一种稍弱的同步机制。用来将变量的更新操作同步到其他线程,保证可见性,保证线程等到的变量值是最新的
注:JDK1.4 及更早版本的 volatile 会导致双重检查锁失效

public class Singleton() {
  private volatile static Singleton uniqueSingleton;

  private Singleton() {}

  public static Singleton getInstance() {
    if (uniqueSingleton == null) {
      synchronized (Singleton.class) {
        if (uniqueSingleton == null) {
          uniqueSingleton = new Singleton();
        }
      }
    }
    return uniqueSingleton;
  }
}

# 要点

  • 单例模式确保程序中一个类最多只有一个实例。
  • 单例模式也提供访问这个实例的全局点。
  • 在Java中实现单例模式需要私有的构造器、一个静态方法和一个静态变量。
  • 确定在性能和资源上的限制,然后小心地选择适当的方案来实现单例,以解决多线程的问题(我们必须认定所有的程序都是多线程的)。
  • 如果不是采用JDK1.5以上,双重检查加锁实现会失效。
  • 小心,你如果使用多个类加载器,可能导致单例失效而产生多个实例。

    由于每个类加载器都定义了一个命名空间,如果有多个类加载器,会导致同一个类被加载多次,造成多个单例模式并存的现象。解决办法是:执行指定类加载器,并指定同一个类加载器。

  • 如果使用JVM1.2或之前的版本,你必须建立单例注册表,以免垃圾收集器将单例回收。

    谣言:垃圾收集器会吃掉单例。Java1.2之前,垃圾收集器有个bug,单例没有全局引用(只有单例类引用自身)的时候会被当做垃圾清除。1.2 以后已修复。

编辑 (opens new window)
上次更新: 2022/08/11, 00:48:36
工厂模式
命令模式

← 工厂模式 命令模式→

Theme by Vdoing | Copyright © 2022-2025 Ai | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×