theme: fancy

前言

  • 前面铺掉了那么多都是在讲原则,讲图例。很多同学可能都觉得和设计模式不是很搭边。虽说设计模式也是理论的东西,但是设计原则可能对我们理解而言更加的抽象。不过好在原则东西不是很多,后面我们就可以开始转讲设计模式了。
  • 我的思路是按照设计模式进行分类整理。期间穿插相关的知识进行扩展从而保证我们学习的更加的全面。在正式开始前我现在这里立个Flag。争取在20周内完成我们设计模式章节的内容。期间可能会有别的学习,20周争取吧
  • 相信单例模式是大家第一个使用到的设计模式吧。不管你怎么样,我第一个使用的就是单例模式。其实单例模式也是分很多种的【饿汉式】、【懒汉式】。如果在细分还有线程安全和线程不安全版本的。

饿汉式

  • 顾名思义饿汉式就是对类需求很迫切。从Java角度看就是类随着JVM启动就开始创建,不管你是否使用到只要JVM启动就会创建。
 public class SingleFactory
 {
     private static Person person = new Person();
 ​
     private SingleFactory()
    {
    }
 ​
     public static Person getInstance()
    {
         return person;
    }
 }
  • 上面这段代码就是饿汉式单例模式。通过这单代码我们也能够总结出单例模式的几个特点
  • 特点
    隐藏类的创建即外部无法进行创建
    内部初始化好一个完整的类
    提供一个可以访问到内部实例的方法,这里指的是getInstance

  • 单例模式特点还是很容易区分的。饿汉式感觉挺好的,那为什么后面还会出现懒汉式及其相关的变形呢?下面我们就来看看饿汉式有啥缺点吧。
  • 首先上面我们提到饿汉式的标志性特点就是随着JVM 的启动开始生成实例对象。这是优点同时也是缺点。大家应该都用过Mybatis等框架,这些框架为了加快我们程序的启动速度纷纷推出各种懒加载机制。
  • 何为懒加载呢?就是用到的时候再去初始化相关业务,将和启动不相关的部分抽离出去,这样启动速度自然就快了起来了。在回到饿汉式,你不管三七二十一就把我给创建了这无疑影响了我的程序启动速度。如果这个单例模式你使用了倒还好,假如启动之后压根就没用到这个单例模式的类,那我岂不是吃力不讨好。不仅浪费了时间还浪费了我的空间。
  • 所以说,处于对性能的考虑呢?还是建议大家不要使用饿汉式单例。但是,存在即是合理的,我们不能一棒子打死一堆人。具体场景具体对待吧XDM。

变形1

 public class SingleFactory
 {
     private static Person person ;
 ​
     static {
         person = new Person();
    }
 ​
     private SingleFactory()
    {
    }
 ​
     public static Person getInstance()
    {
         return person;
    }
 }
  • 咋一看好像和上面的没啥区别哦。仔细对比你就会发现我们这里并没有立刻创建Person这个类,而是放在静态代码块中初始化实例了。
  • 放在静态代码块和直接创建其实是一样的。都是通过类加载的方式来进行实例化的。基本同根同源没啥可说的 。
  • 关于Static关键字我们之前也有说过,他涉及到的是类加载的顺序。我们在类加载的最后阶段就是执行我们的静态代码块

懒汉式

 public class SingleFactory
 {
     private static Person person = null;
 ​
     private SingleFactory()
    {
    }
 ​
     public static Person getInstance()
    {
         try
        {
             Thread.sleep(30);
        }
         catch (InterruptedException e)
        {
            e.printStackTrace();
        }
         if(person==null){
             person=new Person();
        }
         return person;
    }
 }
  • 懒汉式就是将我们的对象创建放在最后一刻进行创建。并不是跟随类加载的时候生成对象的,这样会造成一定程度的内存浪费。懒汉式更加的提高了内存的有效利用。在getInstance方法中我们在获取对象前判断是否已经生成过对象。如果没有在生成对象。这种行为俗称懒,所以叫做懒汉式单例模式

变形1

  • 上面懒汉式单例中我加入了睡眠操作。这是因为我想模拟出他的缺点。上面这种方式在高并发的场景下并不能保证系统中仅有一个实例对象。
 public class SingleFactory
 {
     private static Person person = null;
 ​
     private SingleFactory()
    {
    }
 ​
     public static Person getIstance()
    {
         try
        {
             Thread.sleep(30);
        }
         catch (InterruptedException e)
        {
             e.printStackTrace();
        }
         synchronized (SingleFactory.class)
        {
             if (person == null)
            {
                 person = new Person();
            }
        }
         return person;
    }
 }
  • 只需要加一把锁,就能保证线性操作了。但是仔细想想难道这样就真的安全了吗。

double-check

  • 在多线程下安全的单例模式应该非double-check莫属了吧。
 public class OnFactory {
     private static volatile OnFactory onFactory;
 ​
     public static OnFactory getInstance() {
         if (null == onFactory) {
             synchronized (OnFactory.class) {
                 if (null == onFactory) {
                     onFactory = new OnFactory();
                }
            }
        }
         return onFactory;
    }
 }
  • 这段代码是之前咱们学习double-check和volatile的时候写过的一段代码。在这里我们不仅在锁前后都判断了而且还加上了volatile进行内存刷新。关于volatile需要的在主页中搜索关键词即可找到。这里仅需要知道一点volatile必须存在否则线程不安全。

从单例谈double-check必要性,多种单例各取所需的更多相关文章

  1. DCL,即Double Check Lock,中卫双重检查锁定。

    DCL,即Double Check Lock,中卫双重检查锁定. [Java并发编程]之十六:深入Java内存模型——happen-before规则及其对DCL的分析(含代码) 关于单例.关于DCL: ...

  2. java中的双重锁定检查(Double Check Lock)

    原文:http://www.infoq.com/cn/articles/double-checked-locking-with-delay-initialization#theCommentsSect ...

  3. 以TrueType为例谈字形描述

    以TrueType为例谈字形描述 作者:哲思 时间:2022.9.17 邮箱:zhe__si@163.com GitHub:zhe-si (哲思) (github.com) 一.前言 在深入理解&qu ...

  4. (转载)spring单例和多例详解。如何在单例中调用多例对象

    spring生成对象默认是单例的.通过scope属性可以更改为多例. <bean id="user" class="modle.User" scope=& ...

  5. postgresql on centos (sequelize+pg+nodejs):Failed to find PostgresSQL server.Pleast double check your settings

    公司的一个项目,使用的nodejs做服务端,数据库是postgresql,在本地时一切ok,放在centos时,postgresql配置ok,可以远程访问,但是nodejs在centos启动时,就会报 ...

  6. 设计模式——懒汉式单例类PK饿汉式单例类

    前言 我们都知道生活中好多小软件,有的支持多IP在线,有的仅仅局限于单个IP在线.为什么这样设计,在软件开发阶段就是,有需求就是发展.这就是软件开发的一个设计模式--懒汉式单例类和饿汉式单例类. 内容 ...

  7. 以QT为例谈环境搭建

    以QT为例谈环境搭建 作者:哲思 时间:2022.1.5 邮箱:1464445232@qq.com GitHub:zhe-si (哲思) (github.com) 前言 自从实习结束,好久没写博客了. ...

  8. 表单(上)EasyUI Form 表单、EasyUI Validatebox 验证框、EasyUI Combobox 组合框、EasyUI Combo 组合、EasyUI Combotree 组合树

    EasyUI Form 表单 通过 $.fn.form.defaults 重写默认的 defaults. 表单(form)提供多种方法来执行带有表单字段的动作,比如 ajax 提交.加载.清除,等等. ...

  9. Python接口测试实战4(下) - 框架完善:用例基类,用例标签,重新运行上次失败用例

    如有任何学习问题,可以添加作者微信:lockingfree 课程目录 Python接口测试实战1(上)- 接口测试理论 Python接口测试实战1(下)- 接口测试工具的使用 Python接口测试实战 ...

  10. Ext JS4 学习笔记之发送表单(Form)时也将表单下的表格(Grid)数据一同发送的方法

    Ext JS4 学习笔记之发送表单(Form)时也将表单下的表格(Grid)数据一同发送的方法 昨天在开发的时候遇到个小问题,就是如何将Grid的内容与Form一起发送到服务器端.默认情况下,表单(F ...

随机推荐

  1. CCF201503-1图像旋转

    问题描述 旋转是图像处理的基本操作,在这个问题中,你需要将一个图像逆时针旋转90度. 计算机中的图像表示可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可. 输入格式 输入的第一行包含 ...

  2. mixin和composition api

    1. 这两个都是实现组件逻辑复用的法宝 2. composition api是vue3的,  composition api的出现就是解决mixins的不足之处的 一. mixin 回顾下mixin, ...

  3. print,printf,println的区别,以及\r,\n,\r\n的区别

    1.常用的是println,就是换行输出 2.print,不换行输出 3.printf常使用于格式转化 public class Print { public static void main(Str ...

  4. 3.SRE.操作手册:基础篇

    SRE的根基起码应该包括:SLO.监控.告警.减少琐事和简单化. SLO(服务质量目标):用于描述服务可靠性的程度. SRE的职责并不只是将"所有工作"都自动化,并保持" ...

  5. HCNP Routing&Switching之组播技术PIM-SM 稀疏模式

    前文我们了解了组播路由协议PIM以及PIM-DM密集模式相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/16084310.html:今天我们来聊一聊PI ...

  6. (转)Angular中的拦截器Interceptor

    什么是拦截器? 异步操作 例子 Session 注入(请求拦截器) 时间戳(请求和响应拦截器) 请求恢复 (请求异常拦截) Session 恢复 (响应异常拦截器) 转之:http://my.osch ...

  7. SpringCloudAlibaba微服务docker容器打包和部署示例实战

    概述 我们使用前面<SpringCloudAlibaba注册中心与配置中心之利器Nacos实战与源码分析(中)>的两个微服务示例,分别是库存微服务和订单微服务,基于Nacos注册中心和配置 ...

  8. 领域驱动模型DDD(三)——使用Saga管理事务

    前言 虽然一直说想写一篇关于Saga模式,在多次尝试后不得不承认这玩意儿的仿制代码真不是我一个菜鸟就能完成的,所以还是妥协般地引用现成的Eventuate Tram Saga框架(虽然我对它一直很反感 ...

  9. C#/VB.NET 获取Excel中图片所在的行、列坐标位置

    本文以C#和vb.net代码示例展示如何来获取Excel工作表中图片的坐标位置.这里的坐标位置是指图片左上角顶点所在的单元格行和列位置,横坐标即顶点所在的第几列.纵坐标即顶点所在的第几行.下面是获取图 ...

  10. nacos 详细介绍(一)

    一.Nacos介绍 Nacos是SpringCloudAlibaba架构中最重要的组件. Nacos 是一个更易于帮助构建云原生应用的动态服务发现.配置和服务管理平台,提供注册中心.配置中心和动态 D ...