zxpnet网站 zxpnet网站
首页
前端
后端服务器
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

zxpnet

一个爱学习的java开发攻城狮
首页
前端
后端服务器
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 大后端课程视频归档
  • 南航面试题
  • 并发编程

  • 性能调优

  • java8语法

  • lombok

  • 日志

  • 工具类

  • spring

  • mybatis

  • springboot

  • redis

  • zookeeper

  • springcloud

  • dubbo

  • netty

  • springsecurity

  • mq消息中间件

  • shiro

  • beetle

  • 模板引擎

  • jpa

  • 数据结构与算法

  • 数据库知识与设计

  • gradle

  • maven

  • bus

  • 定时任务

  • docker

  • centos

  • 加解密

  • biz业务

    • 公共业务

      • 单例模式
        • 需求
        • 饿汉式:线程安全
        • 懒汉式
        • 双重检验锁模式
      • Untitled
      • 接口与抽象类的应用(包括各自设计模式)
      • SpringBoot使用ApplicationEvent&Listener完成业务解耦
      • 业务异常处理
      • ThreadLocal用法
      • 自定义RequestMappingHandlerMapping实现程序版本控制
    • 商城系统

    • 许愿池

    • 微信公众号

    • 企业微信

    • 分销返利系统

  • pigx项目

  • 开源项目

  • 品达通用权限项目-黑马

  • 货币交易项目coin-尚学堂

  • php

  • backend
  • biz业务
  • 公共业务
shollin
2021-06-21
目录

单例模式

  • 需求
  • 饿汉式:线程安全
  • 懒汉式
  • 双重检验锁模式

# 需求

在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息,显然,这种方式简化了在复杂环境下的配置管理。

  • 确保一个类只有一个实例,并为整个系统提供一个全局访问点 (向整个系统提供这个实例)。
  • 在内存中只有一个对象,节省内存空间;
  • 避免频繁的创建销毁对象,可以提高性能;
  • 避免对共享资源的多重占用,简化访问;
  • 为整个系统提供一个全局访问点。

# 饿汉式:线程安全

在应用启动时,就加载。 主要原理: 在静态方法时就new出对象

// 饿汉式单例
public class Singleton1 {
 
    // 指向自己实例的私有静态引用,主动创建
    private static Singleton1 singleton1 = new Singleton1();
 
    // 私有的构造方法
    private Singleton1(){}
 
    // 以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton1 getSingleton1(){
        return singleton1;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

在线程访问单例对象之前就已经创建好了。再加上,由于一个类在整个生命周期中只会被加载一次,因此该单例类只会创建一个实例,也就是说,线程每次都只能也必定只可以拿到这个唯一的对象。因此就说,饿汉式单例天生就是线程安全的。

# 懒汉式

// 懒汉式单例:线程不安全
public class Singleton2 {
 
    // 指向自己实例的私有静态引用
    private static Singleton2 singleton2;
 
    // 私有的构造方法
    private Singleton2(){}
 
    // 以自己实例为返回值的静态的公有方法,静态工厂方法
    public static Singleton2 getSingleton2(){
        // 被动创建,在真正需要使用时才去创建
        if (singleton2 == null) {
            singleton2 = new Singleton2();
        }
        return singleton2;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 线程安全的懒汉式单例
public class Singleton5 {
 
    // 私有内部类,按需加载,用时加载,也就是延迟加载
    private static class Holder {
        private static Singleton5 singleton5 = new Singleton5();
    }
 
    private Singleton5() {}
 
    public static Singleton5 getSingleton5() {
        return Holder.singleton5;
    }
}

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

参考实现:cn.hutool.core.lang.Singleton

# 双重检验锁模式

/**
 * 双重校验锁方式 创建单例
 *
 */
public class Singleton {

    private Singleton() {}
    private volatile static Singleton myinstance;

    public static Singleton getInstance() {
        if (myinstance == null) { // 同步代码块外非空判断
            synchronized (Singleton.class) {
                if (myinstance == null) { // 同步代码块内非空判断
                    myinstance = new Singleton();
                }
            }
        }
        return myinstance;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

instance = new Singleton()这句,这并非是一个原子操作,事实上在 JVM 中这句话大概做了下面 3 件事情。

1.给 instance 分配内存 2.调用 Singleton 的构造函数来初始化成员变量 3.将instance对象指向分配的内存空间(执行完这步 instance 就为非 null 了)

高并发情况下,cpu会对指令进行指令重排,变成了1-3-2,造成得到一个空对象的可能,因此需要变成volatile变量,杜绝指令重排。

参考文章

【转】线程安全的单例模式 (opens new window)

设计模式--单例模式(二)双重校验锁模式 - ·卿欢· - 博客园 (cnblogs.com) (opens new window)

单例工具-Singleton (hutool.cn) (opens new window)

【单例模式】猛男因不懂单例模式,被面试官无情嘲讽_哔哩哔哩_bilibili (opens new window)

对称与非对称加密
Untitled

← 对称与非对称加密 Untitled→

最近更新
01
国际象棋
09-15
02
成语
09-15
03
自然拼读
09-15
更多文章>
Theme by Vdoing | Copyright © 2019-2023 zxpnet | 粤ICP备14079330号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式