baby sword‘s blog baby sword‘s blog
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)

zhengjian

不敢承担失去的风险,是不可能抓住梦想的
首页
  • java基础
  • java进阶
大数据
  • mysql

    • mysql索引
    • mysql日志
  • redis

    • 单机下的redis
    • 集群下的redis
  • Spring
  • springboot
  • RPC
  • netty
  • mybatis
  • maven
  • 消息队列
  • kafka
  • zookeeper
  • rocketmq
  • 七大设计原则
  • 创建型模式
  • 结构型模式
  • 行为型模式
  • SpringCloud

    • eureka
  • SpringCloud Alibaba

    • nacos
  • 计算机网络
  • 操作系统
  • 算法
  • 个人项目
  • 个人面试面经
  • 八股记忆
  • 工作积累
  • 逻辑题
  • 面试

    • 百度后端实习二面
GitHub (opens new window)
  • 设计模式七大原则
  • 创建型模式

    • 简单工厂模式
    • 工厂方法模式
    • 抽象工厂模式
    • 单例模式
      • 1.简介
      • 2.考虑的问题
      • 3. 代码实现
      • 饿汉式
      • 懒汉式
        • 双重检测
        • 静态内部类
        • 枚举
    • 建造者模式
    • 原型模式
  • 结构型模式

  • 行为型模式

  • UML

  • 设计模式
  • 创建型模式
xugaoyi
2022-12-23
目录

单例模式

# 1.简介

单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。

必须要满足的三个条件:

  1. 单例类的构造函数必须是私有的,这样才能将类的创建权控制在类的内部,从而使得类的外部不能创建类的实例。
  2. 单例类通过一个私有的静态变量来存储其唯一实例。
  3. 单例类通过提供一个公开的静态方法,使得外部使用者可以访问类的唯一实例。

# 2.考虑的问题

  • 创建单例对象时,是否线程安全。
  • 单例对象的创建,是否延时加载。
  • 获取单例对象时,是否需要加锁(锁会导致低性能)。

# 3. 代码实现

# 饿汉式

饿汉式的单例实现比较简单,其在类加载的时候,静态实例instance 就已创建并初始化好了。

public class Singleton { 
  private static final Singleton instance = new Singleton();
  
  private Singleton () {}
  
  public static Singleton getInstance() {
    return instance;
  }
}
1
2
3
4
5
6
7
8
9

饿汉式单例优缺点:

  • 优点:
    • 单例对象的创建是线程安全的;
    • 获取单例对象时不需要加锁。
  • 缺点:单例对象的创建,不是延时加载。

# 懒汉式

懒汉式为了支持延时加载,将对象的创建延迟到了获取对象的时候,但为了线程安全,不得不为获取对象的操作加锁,这就导致了低性能。

并且这把锁只有在第一次创建对象时有用,而之后每次获取对象,这把锁都是一个累赘(双重检测对此进行了改进)。

public class Singleton { 
  private static final Singleton instance;
  
  private Singleton () {}
  
  public static synchronized Singleton getInstance() {    
    if (instance == null) {      
      instance = new Singleton();    
    }    

    return instance;  
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14

懒汉式单例优缺点:

  • 优点:
    • 对象的创建是线程安全的。
    • 支持延时加载。
  • 缺点:获取对象的操作被加上了锁,影响了并发度。
    • 如果单例对象需要频繁使用,那这个缺点就是无法接受的。
    • 如果单例对象不需要频繁使用,那这个缺点也无伤大雅。

# 双重检测

public class Singleton{
    
    private static volatile Singleton instance;
    
    private Singleton(){}
    
    public static Singleton getInstance(){
        if(instance==null){
        	synchronized(this){
                if(instance==null){
                    instance=new Singleton();
                }
            }    
        }
        return instance;
        
    }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

双重检测单例优点:

  • 对象的创建是线程安全的。
  • 支持延时加载。
  • 获取对象时不需要加锁。

# 静态内部类

用静态内部类的方式实现单例类,利用了Java 静态内部类的特性:

  • Java 加载外部类的时候,不会创建内部类的实例,只有在外部类使用到内部类的时候才会创建内部类实例。
public class Singleton { 
  private Singleton () {}

  private static class SingletonInner {
    private static final Singleton instance = new Singleton();
  }
  
  public static Singleton getInstance() {
    return SingletonInner.instance;
  }
}

1
2
3
4
5
6
7
8
9
10
11
12
  • 对象的创建是线程安全的。
  • 支持延时加载。
  • 获取对象时不需要加锁。

# 枚举

用枚举来实现单例,是最简单的方式。这种实现方式通过 Java 枚举类型本身的特性,保证了实例创建的线程安全性和实例的唯一性。

public enum Singleton {
  INSTANCE; // 该对象全局唯一
}
1
2
3
编辑 (opens new window)
上次更新: 2024/02/22, 14:03:19
抽象工厂模式
建造者模式

← 抽象工厂模式 建造者模式→

最近更新
01
spark基础
02-22
02
mysql读写分离和分库分表
02-22
03
数据库迁移
02-22
更多文章>
Theme by Vdoing | Copyright © 2019-2024 Evan Xu | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式