目录

(MS)

1. 饿汉实现

2.  懒汉模式

① 单线程版本

② 线程安全版

③ 线程安全改进版⼀

以上存在线程安全问题。

④ 线程安全改进版⼆

以上存在线程安全问题,对象创建需要三步:

⑤ 线程安全改进最终版


(MS)

单例模式具体的实现⽅式, 分成 "饿汉" 和 "懒汉" 两种:
● 饿汉⽅式:程序启动之后,里面创建单例对象。(线程安全,可能会造成资源浪费)
● 懒汉⽅式:当有程序调用单例对象的时候才初始化。(使⽤时才加载,可以避免资源不必要的浪费)

单例模式的实现:

无论是饿汉还是懒汉,实现的模式是一模一样的,分为3种:

        1. 创建 一个私有的构造函数(为防止其他类直接new此对象)。

        2. 创建一个私有的属性对象。

        3. 创建一个公共的对外暴露的单例对象。

默认的懒汉模式是⾮线程安全的,使⽤要对懒汉进⾏优化,优化改进:
        ● 全局加锁(线程安全、性能⽐较低)
        ● 局部加锁(线程安全,双重效验)

1. 饿汉实现

程序执行起来之后,执行是一次性的,是线程安全的,会造成资源的浪费。

饿汉实现
public class DataSourceSingleton {//1. 提供私有的构造方法,(防止外部直接new对象)private DataSourceSingleton() {}//2. 创建一个私有的属性对象private static DataSourceSingleton dataSource = new DataSourceSingleton();//提供公共的对外的单例对象public static DataSourceSingleton getInstance() {return dataSource;}
}

2.  懒汉模式

为了解决饿汉模式造成的资源浪费,产生了懒汉模式。

① 单线程版本

单例模式——懒汉模式 1 单线程版本public class DataSourceSingleton2 {// 1.私有的构造方法private DataSourceSingleton2() {}// 2.创建一个私有的属性private static DataSourceSingleton2 dataSource = null;// 3.创建一个对外提供访问的单例对象public  static DataSourceSingleton2 getInstance() {if (dataSource == null) { // 第一次访问dataSource = new DataSourceSingleton2();}return dataSource;}
}

此懒汉模式的实现是线程不安全的.

线程安全问题发⽣在⾸次创建实例时. 如果在多个线程中同时调⽤ getInstance ⽅法, 就可能导致创建出多个实例.
⼀旦实例已经创建好了, 后⾯再多线程环境调⽤ getInstance 就不再有线程安全问题了(不再修改 instance 了)。

② 线程安全版

单例模式——懒汉模式2 线程安全版
public class DataSourceSingleton3 {// 1.私有的构造方法private DataSourceSingleton3() {}// 2.创建一个私有的属性private static DataSourceSingleton3 dataSource;// 3.创建一个对外提供访问的单例对象public synchronized static DataSourceSingleton3 getInstance() {if (dataSource == null) { // 第一次访问//可能会出问题dataSource = new DataSourceSingleton3();}return dataSource;}
}

虽然线程安全,但给全局加锁,性能不好。  

③ 线程安全改进版⼀

单例模式--懒汉模式3  线程安全改进版⼀
public class DataSourceSingleton4 {// 1. 私有的构造方法private DataSourceSingleton4() {}// 2. 私有的属性private static DataSourceSingleton4 dataSource = null;// 3. 公共的访问方法,得到单例对象public static DataSourceSingleton4 getInstance() {//在返回dataSourse的之前,要先判断,是不是第一次访问,如果是第一次访问,需要new一个对象,此时,存在线程安全问题if(dataSource == null) { // 大致分流状态synchronized (DataSourceSingleton4.class) {dataSource = new DataSourceSingleton4(); // 加上synchronized (),问题仍没有解决}}return dataSource;}
}

以上存在线程安全问题。

④ 线程安全改进版⼆

单例模式--懒汉模式4 线程安全改进版⼆
public class DataSourceSingleton5 {// 1. 私有的构造方法private DataSourceSingleton5() {}// 2. 私有的属性private static DataSourceSingleton5 dataSource = null;// 3. 公共的访问方法,得到单例对象public static DataSourceSingleton5 getInstance() {//在返回dataSourse的之前,要先判断,是不是第一次访问,如果是第一次访问,需要new一个对象,此时,存在线程安全问题// 加上synchronized (),问题仍没有解决//在synchronized ()内部再次判断是不是第一次访问if(dataSource == null) { // 大致分流状态synchronized (DataSourceSingleton4.class) {if(dataSource == null) { // 精细化的分流(DCL双重效验锁)dataSource = new DataSourceSingleton5();}}}return dataSource;}
}

以上存在线程安全问题,对象创建需要三步:

        1. 给对象分配内存

        2. 初始化对象

        3. 设置对象到相应的内存地址上

假如因为指令重排导致执⾏的顺序变为了132,那么假如a线程中执⾏完1、3之后,b线程到达代码2处.执⾏判断语句,发现instance指向的是⼀段地址,因此直接不进⼊判断语句⽽是直接返回了⼀个没有初始化的空的对象。

⑤ 线程安全改进最终版

单例模式--懒汉模式5 线程安全改进最终版
public class DataSourceSingleton6 {// 1. 私有的构造方法private DataSourceSingleton6() {}// 2. 私有的属性private static volatile DataSourceSingleton6 dataSource = null;// 3. 公共的访问方法,得到单例对象public static DataSourceSingleton6 getInstance() {//在返回dataSourse的之前,要先判断,是不是第一次访问,如果是第一次访问,需要new一个对象,此时,存在线程安全问题// 加上synchronized (),问题仍没有解决//在synchronized ()内部再次判断是不是第一次访问if(dataSource == null) { // 大致分流状态synchronized (DataSourceSingleton4.class) {if(dataSource == null) { // 精细化的分流(DCL双重效验锁)dataSource = new DataSourceSingleton6();}}}return dataSource;}
}

单例模式(饿汉实现、懒汉实现)相关推荐

  1. 单例模式 (饿汉、懒汉)

    单例模式 定义 单例模式的实现 饿汉模式 懒汉模式 线程安全问题分析: 如何解决线程安全问题?? 关键点总结 定义 单例模式,是一种常见的"设计模式" 设计模式: 设计模式是一套经 ...

  2. 单例模式——饿汉模式懒汉模式

    目录 一.什么是单例模式? 二.单例模式的应用场景 三.两种典型的方式实现单例模式 1.饿汉模式 2.懒汉模式 3.理解懒汉模式和饿汉模式 四.单例模式和线程的关系 1.饿汉模式是否线程安全? 2.懒 ...

  3. DBCP使用BasicdataSource连接(两种单例模式-----饿汉和懒汉模式)

    DBCP使用BasicDataSource连接 BasicDataSource实现DataSource的接口,可以进行简单的数据库连接 第一种:懒汉模式:顾名思义,"懒",只有在调 ...

  4. 单例模式之饿汉和懒汉(java)

    文章目录 1.前言 2.怎么区分饿汉和懒汉模式 3. 饿汉 4.懒汉 (双重检查 Double Check Lock) 5.饿汉模式在JDK中的应用(Runtime) 6.相关文章 1.前言 面试时, ...

  5. 单例模式饿汉模式与懒汉模式

    目录 1.什么是单例模式 2.为什么需要单例模式? 3.如何实现单例模式 3.1饿汉方式 3.2懒汉模式 1.什么是单例模式 单例模式是一种设计模式,单例模式能保证某个类在程序中只存在唯一一份实例, ...

  6. 单例模式之饿汉模式懒汉模式

    前言 单例模式能保证某个类在程序中只存在唯一一份实例,而不会创建出多个实例,比如 JDBC 中的 DataSource 实例就只需要一个.单例模式具体的实现方式有"饿汉" 和 &q ...

  7. 单例模式,饿汉与懒汉

    文章目录 什么是单例模式 单例模式的两种形式 饿汉模式 懒汉模式 懒汉模式与饿汉模式是否线程安全 懒汉模式的优化 什么是单例模式 单例模式其实就是一种设计模式,跟象棋的棋谱一样,给出一些固定的套路帮助 ...

  8. Singleton模式(单例模式) 饿汉式和懒汉式

    目的:整个应用中有且只有一个实例,所有指向该类型实例的引用都指向这个实例. 好比一个国家就只有一个皇帝(XXX),此时每个人叫的"皇帝"都是指叫的XXX本人; 常见单例模式类型: ...

  9. 单例模式——饿汉式和懒汉式

    单例模式:一个类只允许存在唯一的对象,并提供它的访问方式 创建思路: 1.禁止在类的外部创建对象:私有化构造函数 2.在类的内部提供唯一的对象:静态成员变量 3.提供访问唯一对象的方法:静态成员函数 ...

  10. Java-Day12 面向对象的三大特征之封装、继承,单例模式(饿汉式、懒汉式)、方法重写 (覆盖)、注解 (annotation)、super关键字、对象的创建流程超详细

    目录 1. 面向对象的三大特征之封装 1.1 封装的含义 1.2 封装的目的 1.3 封装的优点 1.4 封装的实现过程 1.5 拓展知识:JavaBean 2. 面向对象的三大特征之继承 2.1 继 ...

最新文章

  1. Java基础系列:(2)关于枚举的简单总结
  2. 在ASP.NET MVC 模型中 选择最好的方法将多个model(数据模型)传递到视图
  3. 证券一哥炼成记——郭树清
  4. ios 内存深度优化_iOS 25个性能优化/内存优化常用方法
  5. JS不同类型之间运算与转换
  6. 企业联合体的形式_联合体如何联合?——总包新政下,联合体如何联合?系列三...
  7. mysql数据库应用的权限层级_MySQL数据库的用户权限管理
  8. Java代理系列-静态代理
  9. currency abap_Java Currency getDefaultFractionDigits()方法及示例
  10. mysql csv存储引擎_2.2 mysql存储-CSV存储引擎
  11. 由先序+后序遍历确定序列是否唯一并输出一个中序序列
  12. 二分(POJ - 3273 )
  13. 技嘉linux支持的主板型号,详细解读主板厂商命名规则——技嘉篇
  14. Rockchip BT.656 TX 和 BT.1120 TX 开发指南
  15. 巴巴运动网学习笔记(76-80)
  16. javascript 压缩_14种用于压缩JavaScript的工具
  17. 航母级app横空出世 百事哈哈狂飙蓝海
  18. 初学graphiql 查询操作
  19. 51单片机外部中断的C51编程
  20. PyQt5高级界面控件之QDockWidget

热门文章

  1. 浅淡XSS跨站脚本攻击的防御方法
  2. js指定删除数组中的某个值
  3. 网站使用CDN加速服务,再也不用担心网站打开速度慢了!
  4. 创业公司打造“A级团队”的七个方法
  5. 叮咚谁呀我是送信的邮递员呀_听说游戏内容
  6. 《数据仓库与数据挖掘》期末复习总结(1)
  7. 刘泉承的程序设计笔记 第一篇 11月11日
  8. 关于Excel的问题,不可编辑的区域--控件
  9. Oracle之Hint使用总结
  10. idea建包怎么分级